"database/sql"
"errors"
"fmt"
+ "reflect"
)
const (
func IsFin[T any](t *SqlTx[T]) bool {
return t == nil || t.fin
}
+
+func DealRows[T any](rows *sql.Rows, createF func() T) ([]T, error) {
+ rowNames, err := rows.Columns()
+ if err != nil {
+ return nil, err
+ }
+ var res []T
+
+ for rows.Next() {
+ rowP := make([]any, len(rowNames))
+ for i := 0; i < len(rowNames); i++ {
+ rowP[i] = new(any)
+ }
+
+ err = rows.Scan(rowP...)
+ if err != nil {
+ return nil, err
+ }
+
+ var rowT = createF()
+ refV := reflect.ValueOf(&rowT)
+ for i := 0; i < len(rowNames); i++ {
+ v := refV.Elem().FieldByName(rowNames[i])
+ if v.IsValid() {
+ if v.CanSet() {
+ val := reflect.ValueOf(*rowP[i].(*any))
+ if val.Kind() == v.Kind() {
+ v.Set(val)
+ } else {
+ return nil, fmt.Errorf("reflectFail:%s KindNotMatch:%v !> %v", rowNames[i], val.Kind(), v.Kind())
+ }
+ } else {
+ return nil, fmt.Errorf("reflectFail:%s CanSet:%v", rowNames[i], v.CanSet())
+ }
+ }
+ }
+ res = append(res, rowT)
+
+ }
+
+ return res, nil
+}
conn, _ := db.Conn(context.Background())
if e := BeginTx[any](conn, context.Background(), &sql.TxOptions{}).Do(SqlFunc[any]{
Ty: Execf,
- Query: "create table log123 (msg text)",
+ Query: "create table log123 (msg text,msg2 text)",
}).Fin(); e != nil {
t.Fatal(e)
}
tx1 := BeginTx[any](db, context.Background(), &sql.TxOptions{}).Do(SqlFunc[any]{
Ty: Execf,
- Query: "insert into log123 values ('1')",
+ Query: "insert into log123 values ('1','a')",
})
tx2 := BeginTx[any](db, context.Background(), &sql.TxOptions{}).Do(SqlFunc[any]{
Ty: Execf,
- Query: "insert into log123 values ('2')",
+ Query: "insert into log123 values ('2','b')",
})
if e := tx1.Fin(); e != nil {
tx1 = BeginTx[any](db, context.Background(), &sql.TxOptions{}).Do(SqlFunc[any]{
Ty: Queryf,
- Query: "select count(1) as c from log123",
+ Query: "select 1 as Msg, msg2 as Msg2 from log123",
AfterQF: func(_ *any, rows *sql.Rows, txE error) (_ *any, stopErr error) {
- for rows.Next() {
- var row int64
- stopErr = rows.Scan(&row)
- if row != 2 {
+ type logg struct {
+ Msg int64
+ Msg2 string
+ }
+
+ if v, err := DealRows(rows, func() logg { return logg{} }); err != nil {
+ return nil, err
+ } else {
+ if v[0].Msg2 != "a" {
+ t.Fatal()
+ }
+ if v[1].Msg2 != "b" {
t.Fatal()
}
}
if e := tx1.Fin(); e != nil {
t.Fatal(e)
}
-
- time.Sleep(time.Second)
}
func TestMain4(t *testing.T) {