Skip to content

Commit 1082170

Browse files
committed
Added Scan/Value drivers for sql support.
1 parent bf57265 commit 1082170

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

sql.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// Copyright 2018-2025 Cristian Maglie. All rights reserved.
3+
// Use of this source code is governed by a BSD-style
4+
// license that can be found in the LICENSE file.
5+
//
6+
7+
package semver
8+
9+
import (
10+
"database/sql/driver"
11+
"fmt"
12+
)
13+
14+
// Scan implements the sql.Scanner interface
15+
func (v *Version) Scan(value interface{}) error {
16+
raw, ok := value.(string)
17+
if !ok {
18+
return fmt.Errorf("incompatible type %T for Version", value)
19+
}
20+
21+
v.raw = raw
22+
v.bytes = []byte(v.raw)
23+
if err := parse(v); err != nil {
24+
return err
25+
}
26+
return nil
27+
}
28+
29+
// Value implements the driver.Valuer interface
30+
func (v *Version) Value() (driver.Value, error) {
31+
return v.raw, nil
32+
}
33+
34+
// Scan implements the sql.Scanner interface
35+
func (v *RelaxedVersion) Scan(value interface{}) error {
36+
raw, ok := value.(string)
37+
if !ok {
38+
return fmt.Errorf("incompatible type %T for Version", value)
39+
}
40+
41+
res := ParseRelaxed(raw)
42+
*v = *res
43+
return nil
44+
}
45+
46+
// Value implements the driver.Valuer interface
47+
func (v *RelaxedVersion) Value() (driver.Value, error) {
48+
if v.version != nil {
49+
return v.version.raw, nil
50+
}
51+
return string(v.customversion), nil
52+
}

sql_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//
2+
// Copyright 2018-2025 Cristian Maglie. All rights reserved.
3+
// Use of this source code is governed by a BSD-style
4+
// license that can be found in the LICENSE file.
5+
//
6+
7+
package semver
8+
9+
import (
10+
"database/sql/driver"
11+
"testing"
12+
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
func TestSQLDriverInterfaces(t *testing.T) {
17+
18+
t.Run("Version", func(t *testing.T) {
19+
// Test Version Scan/Value
20+
v := &Version{}
21+
if _, ok := interface{}(v).(driver.Valuer); !ok {
22+
t.Error("Version does not implement driver.Valuer")
23+
}
24+
if _, ok := interface{}(v).(driver.Valuer); !ok {
25+
t.Error("Version does not implement driver.Valuer")
26+
}
27+
require.Error(t, v.Scan(1))
28+
require.Error(t, v.Scan(nil))
29+
require.NoError(t, v.Scan("1.2.3-rc.1+build.2"))
30+
require.Equal(t, "1.2.3-rc.1+build.2", v.String())
31+
d, err := v.Value()
32+
require.NoError(t, err)
33+
require.Equal(t, "1.2.3-rc.1+build.2", d)
34+
})
35+
36+
t.Run("RelaxedVersion", func(t *testing.T) {
37+
// Test RelaxedVersion Scan/Value
38+
rv := &RelaxedVersion{}
39+
if _, ok := interface{}(rv).(driver.Valuer); !ok {
40+
t.Error("RelaxedVersion does not implement driver.Valuer")
41+
}
42+
if _, ok := interface{}(rv).(driver.Valuer); !ok {
43+
t.Error("RelaxedVersion does not implement driver.Valuer")
44+
}
45+
require.Error(t, rv.Scan(1))
46+
require.Error(t, rv.Scan(nil))
47+
require.NoError(t, rv.Scan("4.5.6-rc.1+build.2"))
48+
require.Equal(t, "4.5.6-rc.1+build.2", rv.String())
49+
rd, err := rv.Value()
50+
require.NoError(t, err)
51+
require.Equal(t, "4.5.6-rc.1+build.2", rd)
52+
53+
require.NoError(t, rv.Scan("1-2.2-3.3"))
54+
require.Equal(t, "1-2.2-3.3", rv.String())
55+
rd2, err := rv.Value()
56+
require.NoError(t, err)
57+
require.Equal(t, "1-2.2-3.3", rd2)
58+
})
59+
}

0 commit comments

Comments
 (0)