Skip to content

Commit

Permalink
Fix option to handle type conversion.
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsoltan committed Jul 14, 2024
1 parent 1fa409c commit 08d14d2
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ go.work
cover.out
cover.html
.vscode
.idea
12 changes: 11 additions & 1 deletion option.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,16 @@ func (o *Option[T]) Scan(src any) error {
}
}

// we try to convertAssign values that we can't directly assign because ConvertValue
// will return immediately for v that is already a Value, even if it is a different
// Value type than the one we expect here.
var st sql.Null[T]

Check failure on line 303 in option.go

View workflow job for this annotation

GitHub Actions / build (1.18)

undefined: sql.Null

Check failure on line 303 in option.go

View workflow job for this annotation

GitHub Actions / build (1.19)

undefined: sql.Null

Check failure on line 303 in option.go

View workflow job for this annotation

GitHub Actions / build (1.20)

undefined: sql.Null

Check failure on line 303 in option.go

View workflow job for this annotation

GitHub Actions / build (1.21)

undefined: sql.Null
if err := st.Scan(src); err == nil {
o.isPresent = true
o.value = st.V
return nil
}

return fmt.Errorf("failed to scan Option[T]")
}

Expand All @@ -306,7 +316,7 @@ func (o Option[T]) Value() (driver.Value, error) {
return nil, nil
}

return o.value, nil
return driver.DefaultParameterConverter.ConvertValue(o.value)
}

// leftValue returns an error if the Option is None, otherwise nil
Expand Down
30 changes: 30 additions & 0 deletions option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,25 @@ func TestOptionScan(t *testing.T) {
is.Equal(err2Exp, err2)
}

func TestOptionScanWithPossibleConvert(t *testing.T) {
is := assert.New(t)

// As passed by the sql package in some cases, src is a []byte.
// https://github.com/golang/go/blob/071b8d51c1a70fa6b12f0bed2e93370e193333fd/src/database/sql/convert.go#L396
src1 := []byte{65, 66, 67}
dest1 := None[string]()
src2 := int32(32)
dest2 := None[int]()

err1 := dest1.Scan(src1)
err2 := dest2.Scan(src2)

is.Nil(err1)
is.Equal(Some("ABC"), dest1)
is.Nil(err2)
is.Equal(Some(32), dest2)
}

func TestOptionValue(t *testing.T) {
is := assert.New(t)

Expand All @@ -425,6 +444,17 @@ func TestOptionValue(t *testing.T) {
is.Nil(err2)
}

func TestOptionValueWithPossibleConvert(t *testing.T) {
is := assert.New(t)

opt := Some(uint32(42))
expected := int64(42)

value, err := opt.Value()
is.Nil(err)
is.Equal(expected, value)
}

type SomeScanner struct {
Cool bool
Some int
Expand Down

0 comments on commit 08d14d2

Please sign in to comment.