diff --git a/lazy.go b/lazy.go index 7fe7707..a0d54e0 100644 --- a/lazy.go +++ b/lazy.go @@ -8,6 +8,7 @@ import ( "math/rand/v2" "reflect" "regexp" + "time" "github.com/jmoiron/sqlx" ) @@ -20,8 +21,15 @@ const ( DB_TAG = "db" //tag used to parse sql fields in example struct LAZY_TAG = "lazy" //tag label for KEY_VALUE KEY_VALUE = "key" //tag value for LAZY_TAG + //bind values + BindQuestion Binds = 1 + BindDollar Binds = 2 + BindNamed Binds = 3 + BindAt Binds = 4 ) +type Binds int + // mock data generated based on config type Mock struct { Query string @@ -35,11 +43,11 @@ type Config struct { Example any Keys []any //length of keys must = RowCount, if set RowCount int + BindType Binds } // generates mock data based on configuration to be used for sqlmock func RandomGenerate(m Config) (*Mock, error) { - fmt.Println("huh") //example struct cannot be nil and must be a struct if m.Example == nil { return nil, errors.New("example value cannot be nil") @@ -91,30 +99,62 @@ func RandomGenerate(m Config) (*Mock, error) { //generate random values nv := kindToRandom(field) if nv == nil { - //this will catch the sql.Null* types, although not slices of them. In these statements it should be - //50/50 chance of null vs value and then psuedo random from there - //1. Write simple 50/50 function - //2. move this logic to nullKindToRandom function - //3. add bind type option to allow for more than just AT now that I'm using postgres + //move this logic to nullKindToRandom function + nullType := false switch field.Type { case reflect.TypeOf(sql.NullTime{}): - // + if isNull() { + rows[y] = append(rows[y], nil) + } else { + rows[y] = append(rows[y], time.Now()) + } + nullType = true case reflect.TypeOf(sql.NullInt16{}): - // + if isNull() { + rows[y] = append(rows[y], nil) + } else { + rows[y] = append(rows[y], rand.Int()) + } + nullType = true case reflect.TypeOf(sql.NullInt32{}): - // + if isNull() { + rows[y] = append(rows[y], nil) + } else { + rows[y] = append(rows[y], rand.Int32()) + } + nullType = true case reflect.TypeOf(sql.NullInt64{}): - // + if isNull() { + rows[y] = append(rows[y], nil) + } else { + rows[y] = append(rows[y], rand.Int64()) + } + nullType = true case reflect.TypeOf(sql.NullBool{}): - // + if isNull() { + rows[y] = append(rows[y], nil) + } else { + rows[y] = append(rows[y], rand.Int()%2 == 0) + } + nullType = true case reflect.TypeOf(sql.NullFloat64{}): - // + if isNull() { + rows[y] = append(rows[y], nil) + } else { + rows[y] = append(rows[y], rand.Float64()) + } + nullType = true case reflect.TypeOf(sql.NullString{}): - // - case reflect.TypeOf(sql.NullByte{}): - // + if isNull() { + rows[y] = append(rows[y], nil) + } else { + rows[y] = append(rows[y], fmt.Sprintf("random %d", rand.Int())) + } + nullType = true + } + if !nullType { + return nil, fmt.Errorf("could not match type: %s", retType.Name()) } - return nil, fmt.Errorf("could not match type: %s", retType.Name()) } rows[y] = append(rows[y], nv) @@ -123,7 +163,7 @@ func RandomGenerate(m Config) (*Mock, error) { return &Mock{ //sql is rebound and escaped for sqlmock.ExpectQuery - Query: sqlx.Rebind(sqlx.AT, regexp.QuoteMeta(m.Query)), + Query: sqlx.Rebind(int(m.BindType), regexp.QuoteMeta(m.Query)), Columns: columns, Rows: rows, }, nil @@ -144,9 +184,11 @@ func kindToRandom(field reflect.StructField) any { case reflect.Float64: return rand.Float64() case reflect.String: - return fmt.Sprintf("%d", rand.Int()) + return fmt.Sprintf("random %d", rand.Int()) case reflect.Bool: return rand.Int()%2 == 0 + case reflect.TypeOf(time.Time{}).Kind(): + return time.Now() case reflect.Array: underlying := field.Type.Elem().Kind() count := reflect.ValueOf(field).Len() //fill entire length @@ -245,3 +287,12 @@ func kindToRandom(field reflect.StructField) any { return nil } + +func isNull() bool { + x := rand.IntN(2) + if x%2 == 0 { + return true + } else { + return false + } +}