Files
lazy/lazy.go
2025-09-26 16:33:24 -04:00

111 lines
2.3 KiB
Go

package lazy
import (
"database/sql/driver"
"errors"
"fmt"
"math/rand/v2"
"reflect"
"regexp"
"github.com/jmoiron/sqlx"
)
type MockResults struct {
Query string
Columns []string
Rows [][]driver.Value
}
func GenerateRandomResults(query string, exampleObj any, keyVal []any, rowCount int) (*MockResults, error) {
if exampleObj == nil {
return nil, errors.New("exampleObj cannot be nil")
}
if rowCount == 0 {
rowCount = 1
}
if len(keyVal) != 0 {
if len(keyVal) != rowCount {
return nil, errors.New("you must provide a key for each row")
}
}
retType := reflect.TypeOf(exampleObj)
maxFieldCount := retType.NumField()
columns := make([]string, 0, maxFieldCount)
rows := make([][]driver.Value, 0)
for y := 0; y < rowCount; y++ {
rows = append(rows, make([]driver.Value, 0))
for x := 0; x < maxFieldCount; x++ {
field := retType.Field(x)
dbTag := field.Tag.Get("db")
if dbTag == "" {
continue
}
if y == 0 {
columns = append(columns, dbTag)
}
if field.Tag.Get("test") == "key" {
rows[y] = append(rows[y], keyVal[y])
continue
}
nv := kindToRandom(field)
if nv == nil {
return nil, fmt.Errorf("could not match type: %s", retType.Name())
}
rows[y] = append(rows[y], nv)
}
}
return &MockResults{
Query: sqlx.Rebind(sqlx.AT, regexp.QuoteMeta(query)),
Columns: columns,
Rows: rows,
}, nil
}
func kindToRandom(field reflect.StructField) any {
kind := field.Type.Kind()
switch kind {
case reflect.Int:
return rand.Int()
case reflect.Int32:
return rand.Int32()
case reflect.Int64:
return rand.Int64()
case reflect.Float32:
return rand.Float32()
case reflect.Float64:
return rand.Float64()
case reflect.String:
return fmt.Sprintf("%d", rand.Int())
case reflect.Bool:
return rand.Int()%2 == 0
case reflect.Slice:
underlying := field.Type.Elem().Kind()
switch underlying {
case reflect.Int:
return []int{rand.Int()}
case reflect.Int32:
return []int32{rand.Int32()}
case reflect.Int64:
return []int64{rand.Int64()}
case reflect.Float32:
return []float32{rand.Float32()}
case reflect.Float64:
return []float64{rand.Float64()}
case reflect.String:
return []string{fmt.Sprintf("%d", rand.Int())}
case reflect.Bool:
return []bool{rand.Int()%2 == 0}
}
}
return nil
}