|
|
|
@@ -4,9 +4,11 @@ import (
|
|
|
|
|
"context"
|
|
|
|
|
"database/sql"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
|
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
|
|
|
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
|
|
|
|
"reflect"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type StructScanMode string
|
|
|
|
@@ -89,6 +91,33 @@ func UpdateSingle[TData any](ctx context.Context, q Queryable, tableName string,
|
|
|
|
|
return sqlr, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func UpdateAndQuerySingle[TData any](ctx context.Context, q Queryable, tableName string, v TData, idColumn string, mode StructScanMode, sec StructScanSafety) (TData, error) {
|
|
|
|
|
|
|
|
|
|
rval := reflect.ValueOf(v)
|
|
|
|
|
|
|
|
|
|
idRVal := rval.FieldByName(idColumn)
|
|
|
|
|
if !idRVal.IsValid() || idRVal.IsZero() {
|
|
|
|
|
return *new(TData), fmt.Errorf("failed to find idColumn '%s' in %T", idColumn, v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
idValue, err := convertValueToDB(q, idRVal.Interface())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return *new(TData), err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, err = UpdateSingle[TData](ctx, q, tableName, v, idColumn)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return *new(TData), err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pp := PP{}
|
|
|
|
|
|
|
|
|
|
//goland:noinspection ALL
|
|
|
|
|
sqlstr := fmt.Sprintf("SELECT * FROM %s WHERE %s = :%s", tableName, idColumn, pp.Add(idValue))
|
|
|
|
|
|
|
|
|
|
return QuerySingle[TData](ctx, q, sqlstr, pp, mode, sec)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func QuerySingle[TData any](ctx context.Context, q Queryable, sql string, pp PP, mode StructScanMode, sec StructScanSafety) (TData, error) {
|
|
|
|
|
rows, err := q.Query(ctx, sql, pp)
|
|
|
|
|
if err != nil {
|
|
|
|
@@ -103,6 +132,23 @@ func QuerySingle[TData any](ctx context.Context, q Queryable, sql string, pp PP,
|
|
|
|
|
return data, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func QuerySingleOpt[TData any](ctx context.Context, q Queryable, sqlstr string, pp PP, mode StructScanMode, sec StructScanSafety) (*TData, error) {
|
|
|
|
|
rows, err := q.Query(ctx, sqlstr, pp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data, err := ScanSingle[TData](ctx, q, rows, mode, sec, true)
|
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &data, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func QueryAll[TData any](ctx context.Context, q Queryable, sql string, pp PP, mode StructScanMode, sec StructScanSafety) ([]TData, error) {
|
|
|
|
|
rows, err := q.Query(ctx, sql, pp)
|
|
|
|
|
if err != nil {
|
|
|
|
|