Skip to content

Commit ec0f388

Browse files
committed
types.Make{Int,String}: Variadic transformer functions
The MakeString function got another variadic parameter, allowing multiple transformers against the newly created String. As one example, the newly introduced TransformEmptyStringToNull function can be used, mimicking Icinga Notifications' ToDBString behavior. To replace Icinga Notifications' ToDBInt utility function, a similar MakeInt function and TransformIntZeroToNull was introduced. Inspired by: - ToDBInt, Icinga/icinga-notifications@f0b39f0 - ToDBString, Icinga/icinga-notifications@8183344
1 parent e543ee2 commit ec0f388

File tree

4 files changed

+120
-11
lines changed

4 files changed

+120
-11
lines changed

types/int.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,28 @@ type Int struct {
1414
sql.NullInt64
1515
}
1616

17+
// TransformIntZeroToNull transforms a valid Int carrying a zero value to a SQL NULL.
18+
func TransformIntZeroToNull(i *Int) {
19+
if i.Valid && i.Int64 == 0 {
20+
i.Valid = false
21+
}
22+
}
23+
24+
// MakeInt constructs a new Int.
25+
//
26+
// Multiple transformer functions can be given, each transforming the generated Int, e.g., TransformIntZeroToNull.
27+
func MakeInt(in int64, transformers ...func(*Int)) Int {
28+
i := Int{sql.NullInt64{
29+
Int64: in,
30+
Valid: true,
31+
}}
32+
33+
for _, transformer := range transformers {
34+
transformer(&i)
35+
}
36+
return i
37+
}
38+
1739
// MarshalJSON implements the json.Marshaler interface.
1840
// Supports JSON null.
1941
func (i Int) MarshalJSON() ([]byte, error) {

types/int_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,49 @@ import (
66
"testing"
77
)
88

9+
func TestMakeInt(t *testing.T) {
10+
subtests := []struct {
11+
name string
12+
input int64
13+
transformers []func(*Int)
14+
output sql.NullInt64
15+
}{
16+
{
17+
name: "zero",
18+
input: 0,
19+
output: sql.NullInt64{Int64: 0, Valid: true},
20+
},
21+
{
22+
name: "positive",
23+
input: 1,
24+
output: sql.NullInt64{Int64: 1, Valid: true},
25+
},
26+
{
27+
name: "negative",
28+
input: -1,
29+
output: sql.NullInt64{Int64: -1, Valid: true},
30+
},
31+
{
32+
name: "zero-transform-zero-to-null",
33+
input: 0,
34+
transformers: []func(*Int){TransformIntZeroToNull},
35+
output: sql.NullInt64{Valid: false},
36+
},
37+
{
38+
name: "positive-transform-zero-to-null",
39+
input: 1,
40+
transformers: []func(*Int){TransformIntZeroToNull},
41+
output: sql.NullInt64{Int64: 1, Valid: true},
42+
},
43+
}
44+
45+
for _, st := range subtests {
46+
t.Run(st.name, func(t *testing.T) {
47+
require.Equal(t, Int{NullInt64: st.output}, MakeInt(st.input, st.transformers...))
48+
})
49+
}
50+
}
51+
952
func TestInt_MarshalJSON(t *testing.T) {
1053
subtests := []struct {
1154
name string

types/string.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,26 @@ type String struct {
1414
sql.NullString
1515
}
1616

17-
// MakeString constructs a new non-NULL String from s.
18-
func MakeString(s string) String {
19-
return String{sql.NullString{
20-
String: s,
17+
// TransformEmptyStringToNull transforms a valid String carrying an empty text to a SQL NULL.
18+
func TransformEmptyStringToNull(s *String) {
19+
if s.Valid && s.String == "" {
20+
s.Valid = false
21+
}
22+
}
23+
24+
// MakeString constructs a new String.
25+
//
26+
// Multiple transformer functions can be given, each transforming the generated String, e.g., TransformEmptyStringToNull.
27+
func MakeString(in string, transformers ...func(*String)) String {
28+
s := String{sql.NullString{
29+
String: in,
2130
Valid: true,
2231
}}
32+
33+
for _, transformer := range transformers {
34+
transformer(&s)
35+
}
36+
return s
2337
}
2438

2539
// MarshalJSON implements the json.Marshaler interface.

types/string_test.go

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,48 @@ import (
99

1010
func TestMakeString(t *testing.T) {
1111
subtests := []struct {
12-
name string
13-
io string
12+
name string
13+
input string
14+
transformers []func(*String)
15+
output sql.NullString
1416
}{
15-
{"empty", ""},
16-
{"nul", "\x00"},
17-
{"space", " "},
18-
{"multiple", "abc"},
17+
{
18+
name: "empty",
19+
input: "",
20+
output: sql.NullString{String: "", Valid: true},
21+
},
22+
{
23+
name: "nul",
24+
input: "\x00",
25+
output: sql.NullString{String: "\x00", Valid: true},
26+
},
27+
{
28+
name: "space",
29+
input: " ",
30+
output: sql.NullString{String: " ", Valid: true},
31+
},
32+
{
33+
name: "valid-text",
34+
input: "abc",
35+
output: sql.NullString{String: "abc", Valid: true},
36+
},
37+
{
38+
name: "empty-transform-empty-to-null",
39+
input: "",
40+
transformers: []func(*String){TransformEmptyStringToNull},
41+
output: sql.NullString{Valid: false},
42+
},
43+
{
44+
name: "valid-text-transform-empty-to-null",
45+
input: "abc",
46+
transformers: []func(*String){TransformEmptyStringToNull},
47+
output: sql.NullString{String: "abc", Valid: true},
48+
},
1949
}
2050

2151
for _, st := range subtests {
2252
t.Run(st.name, func(t *testing.T) {
23-
require.Equal(t, String{NullString: sql.NullString{String: st.io, Valid: true}}, MakeString(st.io))
53+
require.Equal(t, String{NullString: st.output}, MakeString(st.input, st.transformers...))
2454
})
2555
}
2656
}

0 commit comments

Comments
 (0)