goext/sq/scanner.go

141 lines
2.7 KiB
Go
Raw Permalink Normal View History

2022-12-11 03:12:02 +01:00
package sq
import (
"database/sql"
"errors"
"github.com/jmoiron/sqlx"
)
2022-12-22 15:49:10 +01:00
type StructScanMode string
const (
SModeFast StructScanMode = "FAST"
SModeExtended StructScanMode = "EXTENDED"
)
type StructScanSafety string
const (
Safe StructScanSafety = "SAFE"
Unsafe StructScanSafety = "UNSAFE"
)
func ScanSingle[TData any](rows *sqlx.Rows, mode StructScanMode, sec StructScanSafety, close bool) (TData, error) {
2022-12-11 03:12:02 +01:00
if rows.Next() {
2022-12-22 15:49:10 +01:00
var strscan *StructScanner
if sec == Safe {
strscan = NewStructScanner(rows, false)
var data TData
err := strscan.Start(&data)
if err != nil {
return *new(TData), err
}
} else if sec == Unsafe {
strscan = NewStructScanner(rows, true)
var data TData
err := strscan.Start(&data)
if err != nil {
return *new(TData), err
}
} else {
return *new(TData), errors.New("unknown value for <sec>")
}
2022-12-11 03:12:02 +01:00
var data TData
2022-12-22 15:49:10 +01:00
if mode == SModeFast {
err := strscan.StructScanBase(&data)
if err != nil {
return *new(TData), err
}
} else if mode == SModeExtended {
err := strscan.StructScanExt(&data)
if err != nil {
return *new(TData), err
}
} else {
return *new(TData), errors.New("unknown value for <mode>")
2022-12-11 03:12:02 +01:00
}
2022-12-22 15:49:10 +01:00
2022-12-11 03:12:02 +01:00
if rows.Next() {
2022-12-22 15:49:10 +01:00
if close {
_ = rows.Close()
}
return *new(TData), errors.New("sql returned more than one row")
2022-12-11 03:12:02 +01:00
}
2022-12-22 15:49:10 +01:00
2022-12-11 03:12:02 +01:00
if close {
2022-12-22 15:49:10 +01:00
err := rows.Close()
2022-12-11 03:12:02 +01:00
if err != nil {
return *new(TData), err
}
}
2022-12-22 15:49:10 +01:00
2022-12-22 15:55:32 +01:00
if err := rows.Err(); err != nil {
return *new(TData), err
}
2022-12-11 03:12:02 +01:00
return data, nil
2022-12-22 15:49:10 +01:00
2022-12-11 03:12:02 +01:00
} else {
if close {
_ = rows.Close()
}
return *new(TData), sql.ErrNoRows
}
}
2022-12-22 15:49:10 +01:00
func ScanAll[TData any](rows *sqlx.Rows, mode StructScanMode, sec StructScanSafety, close bool) ([]TData, error) {
var strscan *StructScanner
if sec == Safe {
strscan = NewStructScanner(rows, false)
2022-12-11 03:12:02 +01:00
var data TData
2022-12-22 15:49:10 +01:00
err := strscan.Start(&data)
2022-12-11 03:12:02 +01:00
if err != nil {
return nil, err
}
2022-12-22 15:49:10 +01:00
} else if sec == Unsafe {
strscan = NewStructScanner(rows, true)
var data TData
err := strscan.Start(&data)
if err != nil {
return nil, err
}
} else {
return nil, errors.New("unknown value for <sec>")
}
res := make([]TData, 0)
for rows.Next() {
if mode == SModeFast {
var data TData
err := strscan.StructScanBase(&data)
if err != nil {
return nil, err
}
res = append(res, data)
} else if mode == SModeExtended {
var data TData
err := strscan.StructScanExt(&data)
if err != nil {
return nil, err
}
res = append(res, data)
} else {
return nil, errors.New("unknown value for <mode>")
}
2022-12-11 03:12:02 +01:00
}
if close {
2022-12-22 15:49:10 +01:00
err := strscan.rows.Close()
2022-12-11 03:12:02 +01:00
if err != nil {
return nil, err
}
}
2022-12-22 15:55:32 +01:00
if err := rows.Err(); err != nil {
return nil, err
}
2022-12-11 03:12:02 +01:00
return res, nil
}