diff --git a/driver.go b/driver.go index 907aa03..ff58d92 100644 --- a/driver.go +++ b/driver.go @@ -1,6 +1,6 @@ package lazy -//driver.Result does not play well with creation, overriding it here so we can return the results without +//driver.Result does not play well when manually creating them, overriding it here so we can return the results without //requiring sqlmock type sqlResult struct { insertID int64 diff --git a/lazy.go b/lazy.go index 40c8469..1bb15eb 100644 --- a/lazy.go +++ b/lazy.go @@ -18,9 +18,10 @@ const ( ) var ( - ErrBadExample = errors.New("example field must be a non-nil struct") - ErrMissingKeys = errors.New("there must be a key for each row requested with RowCount") - ErrUnsupportedType = errors.New("") + ErrBadExample = errors.New("example field must be a non-nil struct") + ErrMissingKeys = errors.New("there must be a key for each row requested with RowCount") + //contains placeholder to inject type on runtime + ErrUnsupportedType = errors.New("type: %s is not yet supported") ) // mock data generated based on config @@ -34,20 +35,15 @@ type RowMock struct { type RowConfig struct { Query string Example any - Keys []any //if set, length of keys must = RowCount + Keys []any RowCount int } type StructMock struct { - Query string - Args []any - MockStruct any - Result driver.Result -} - -type StructConfig struct { - Query string - Example any + Query string + Args []any + MockStructs reflect.Value + Result driver.Result } // generates mock data based on configuration to be used for sqlmock @@ -102,7 +98,7 @@ func RandomRows(m RowConfig) (*RowMock, error) { //generate random values nv := kindToRandom(field) if nv == nil { - return nil, ErrUnsupportedType + return nil, fmt.Errorf(ErrUnsupportedType.Error(), field.Type.Name()) } rows[y] = append(rows[y], nv) @@ -117,9 +113,7 @@ func RandomRows(m RowConfig) (*RowMock, error) { }, nil } -// so this would "work" but only accounts for inserting one row and doesn't allow for hardcoded ID's -// it would also have to account in the results struct these changes for rowsAffected, etc. -func RandomStruct(c StructConfig) (*StructMock, error) { +func RandomStruct(c RowConfig) (*StructMock, error) { if c.Example == nil { return nil, ErrBadExample } @@ -127,37 +121,46 @@ func RandomStruct(c StructConfig) (*StructMock, error) { return nil, ErrBadExample } + if c.RowCount <= 0 { + c.RowCount = 1 + } + retType := reflect.TypeOf(c.Example) maxFieldCount := retType.NumField() - filled := reflect.New(retType).Elem() + //create slice of structs + ft := reflect.SliceOf(retType) + filled := reflect.MakeSlice(ft, 0, c.RowCount).Elem() args := make([]any, 0, maxFieldCount) - for y := 0; y < maxFieldCount; y++ { - field := retType.Field(y) - dbTag := field.Tag.Get(DB_TAG) - if dbTag == "" { - continue - } + for x := 0; x < c.RowCount; x++ { + for y := 0; y < maxFieldCount; y++ { + field := retType.Field(y) + dbTag := field.Tag.Get(DB_TAG) + if dbTag == "" { + continue + } - nv := kindToRandom(field) - if nv == nil { - return nil, ErrUnsupportedType - } + nv := kindToRandom(field) + if nv == nil { + return nil, fmt.Errorf(ErrUnsupportedType.Error(), field.Type.Name()) + } - args[y] = nv - nf := filled.Field(y) - if nf.CanSet() { - filled.Field(y).Set(reflect.ValueOf(nv)) + args[y] = nv + if x == 0 { + nf := filled.Index(x).Field(y) + if nf.CanSet() { + filled.Index(x).Field(y).Set(reflect.ValueOf(nv)) + } + } } } return &StructMock{ - Query: sqlx.Rebind(sqlx.AT, regexp.QuoteMeta(c.Query)), - Args: args, - MockStruct: filled, + Query: sqlx.Rebind(sqlx.AT, regexp.QuoteMeta(c.Query)), + Args: args, + MockStructs: filled, Result: &sqlResult{ - insertID: 1, - rowsAffected: 1, + rowsAffected: int64(c.RowCount), err: nil, }, }, nil