2025-09-26 15:32:27 -04:00
|
|
|
package lazy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql/driver"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"math/rand/v2"
|
|
|
|
"reflect"
|
|
|
|
"regexp"
|
|
|
|
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
)
|
|
|
|
|
|
|
|
type MockResults struct {
|
|
|
|
Query string
|
|
|
|
Columns []string
|
2025-09-26 16:16:53 -04:00
|
|
|
Rows [][]driver.Value
|
2025-09-26 15:32:27 -04:00
|
|
|
}
|
|
|
|
|
2025-09-26 16:29:36 -04:00
|
|
|
func GenerateRandomResults(query string, exampleObj any, keyVal []any, rowCount int) (*MockResults, error) {
|
2025-09-26 15:32:27 -04:00
|
|
|
if exampleObj == nil {
|
|
|
|
return nil, errors.New("exampleObj cannot be nil")
|
|
|
|
}
|
2025-09-26 16:16:53 -04:00
|
|
|
if rowCount == 0 {
|
|
|
|
rowCount = 1
|
|
|
|
}
|
2025-09-26 16:29:36 -04:00
|
|
|
if len(keyVal) != 0 {
|
|
|
|
if len(keyVal) != rowCount {
|
|
|
|
return nil, errors.New("you must provide a key for each row")
|
|
|
|
}
|
|
|
|
}
|
2025-09-26 15:32:27 -04:00
|
|
|
|
|
|
|
retType := reflect.TypeOf(exampleObj)
|
|
|
|
maxFieldCount := retType.NumField()
|
|
|
|
columns := make([]string, 0, maxFieldCount)
|
2025-09-26 16:18:27 -04:00
|
|
|
rows := make([][]driver.Value, 0)
|
2025-09-26 16:16:53 -04:00
|
|
|
|
|
|
|
for y := 0; y < rowCount; y++ {
|
2025-09-26 16:25:46 -04:00
|
|
|
rows = append(rows, make([]driver.Value, 0))
|
2025-09-26 16:16:53 -04:00
|
|
|
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" {
|
2025-09-26 16:33:24 -04:00
|
|
|
rows[y] = append(rows[y], keyVal[y])
|
2025-09-26 16:16:53 -04:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
nv := kindToRandom(field)
|
|
|
|
if nv == nil {
|
|
|
|
return nil, fmt.Errorf("could not match type: %s", retType.Name())
|
|
|
|
}
|
|
|
|
|
|
|
|
rows[y] = append(rows[y], nv)
|
2025-09-26 15:32:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|