From 10bb5dd44002c897252ae44007c3cf9e369863d6 Mon Sep 17 00:00:00 2001 From: Rowan Seymour Date: Thu, 26 Jan 2023 12:26:36 -0500 Subject: [PATCH] Make envs.Language, envs.Country and envs.Locale play nice with NULLs when persisting --- envs/country.go | 8 +++++++- envs/country_test.go | 15 +++++++++++++++ envs/language.go | 8 +++++++- envs/language_test.go | 15 +++++++++++++++ envs/locale.go | 6 ++++++ envs/locale_test.go | 15 +++++++++++++++ go.mod | 4 +++- go.sum | 11 +++++++++-- 8 files changed, 77 insertions(+), 5 deletions(-) diff --git a/envs/country.go b/envs/country.go index a4cf8f6b7..90036d821 100644 --- a/envs/country.go +++ b/envs/country.go @@ -1,8 +1,10 @@ package envs import ( - "github.com/nyaruka/goflow/utils" + "database/sql/driver" + "github.com/nyaruka/gocommon/dbutil" + "github.com/nyaruka/goflow/utils" "github.com/nyaruka/phonenumbers" validator "gopkg.in/go-playground/validator.v9" ) @@ -27,3 +29,7 @@ func DeriveCountryFromTel(number string) Country { } return Country(phonenumbers.GetRegionCodeForNumber(parsed)) } + +// Place nicely with NULLs if persisting to a database +func (c *Country) Scan(v any) error { return dbutil.ScanNullString(v, c) } +func (c Country) Value() (driver.Value, error) { return dbutil.NullStringValue(c) } diff --git a/envs/country_test.go b/envs/country_test.go index 1e20365d9..dd8469a43 100644 --- a/envs/country_test.go +++ b/envs/country_test.go @@ -12,4 +12,19 @@ func TestDeriveCountryFromTel(t *testing.T) { assert.Equal(t, envs.Country("RW"), envs.DeriveCountryFromTel("+250788383383")) assert.Equal(t, envs.Country("EC"), envs.DeriveCountryFromTel("+593979000000")) assert.Equal(t, envs.NilCountry, envs.DeriveCountryFromTel("1234")) + + v, err := envs.Country("RW").Value() + assert.NoError(t, err) + assert.Equal(t, "RW", v) + + v, err = envs.NilCountry.Value() + assert.NoError(t, err) + assert.Nil(t, v) + + var c envs.Country + assert.NoError(t, c.Scan("RW")) + assert.Equal(t, envs.Country("RW"), c) + + assert.NoError(t, c.Scan(nil)) + assert.Equal(t, envs.NilCountry, c) } diff --git a/envs/language.go b/envs/language.go index d1158f3da..2ac884768 100644 --- a/envs/language.go +++ b/envs/language.go @@ -1,8 +1,10 @@ package envs import ( - "github.com/nyaruka/goflow/utils" + "database/sql/driver" + "github.com/nyaruka/gocommon/dbutil" + "github.com/nyaruka/goflow/utils" "github.com/pkg/errors" "golang.org/x/text/language" "gopkg.in/go-playground/validator.v9" @@ -33,3 +35,7 @@ func ParseLanguage(lang string) (Language, error) { return Language(base.ISO3()), nil } + +// Place nicely with NULLs if persisting to a database +func (l *Language) Scan(v any) error { return dbutil.ScanNullString(v, l) } +func (l Language) Value() (driver.Value, error) { return dbutil.NullStringValue(l) } diff --git a/envs/language_test.go b/envs/language_test.go index ad9152ac4..bcec87e8b 100644 --- a/envs/language_test.go +++ b/envs/language_test.go @@ -18,4 +18,19 @@ func TestLanguage(t *testing.T) { _, err = envs.ParseLanguage("xzx") assert.EqualError(t, err, "unrecognized language code: xzx") + + v, err := envs.Language("eng").Value() + assert.NoError(t, err) + assert.Equal(t, "eng", v) + + v, err = envs.NilLanguage.Value() + assert.NoError(t, err) + assert.Nil(t, v) + + var l envs.Language + assert.NoError(t, l.Scan("eng")) + assert.Equal(t, envs.Language("eng"), l) + + assert.NoError(t, l.Scan(nil)) + assert.Equal(t, envs.NilLanguage, l) } diff --git a/envs/locale.go b/envs/locale.go index b28554d43..889267cc6 100644 --- a/envs/locale.go +++ b/envs/locale.go @@ -1,9 +1,11 @@ package envs import ( + "database/sql/driver" "fmt" "strings" + "github.com/nyaruka/gocommon/dbutil" "golang.org/x/text/language" ) @@ -63,3 +65,7 @@ func (l Locale) ToParts() (Language, Country) { } var NilLocale = Locale("") + +// Place nicely with NULLs if persisting to a database +func (l *Locale) Scan(v any) error { return dbutil.ScanNullString(v, l) } +func (l Locale) Value() (driver.Value, error) { return dbutil.NullStringValue(l) } diff --git a/envs/locale_test.go b/envs/locale_test.go index aa93408c2..c8864becc 100644 --- a/envs/locale_test.go +++ b/envs/locale_test.go @@ -20,6 +20,21 @@ func TestLocale(t *testing.T) { l, c = envs.NilLocale.ToParts() assert.Equal(t, envs.NilLanguage, l) assert.Equal(t, envs.NilCountry, c) + + v, err := envs.NewLocale("eng", "US").Value() + assert.NoError(t, err) + assert.Equal(t, "eng-US", v) + + v, err = envs.NilLanguage.Value() + assert.NoError(t, err) + assert.Nil(t, v) + + var lc envs.Locale + assert.NoError(t, lc.Scan("eng-US")) + assert.Equal(t, envs.Locale("eng-US"), lc) + + assert.NoError(t, lc.Scan(nil)) + assert.Equal(t, envs.NilLocale, lc) } func TestToBCP47(t *testing.T) { diff --git a/go.mod b/go.mod index c6a55a506..ba123876a 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220527190237-ee62e23da966 github.com/blevesearch/segment v0.9.0 github.com/buger/jsonparser v1.1.1 - github.com/nyaruka/gocommon v1.33.1 + github.com/nyaruka/gocommon v1.34.0 github.com/nyaruka/phonenumbers v1.1.4 github.com/olivere/elastic/v7 v7.0.32 github.com/pkg/errors v0.9.1 @@ -29,8 +29,10 @@ require ( github.com/go-playground/universal-translator v0.18.0 // indirect github.com/gofrs/uuid v4.3.1+incompatible // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect google.golang.org/protobuf v1.28.1 // indirect diff --git a/go.sum b/go.sum index 4a4ad8c8b..bac8c0fa2 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -28,6 +30,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -37,11 +40,15 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/nyaruka/gocommon v1.33.1 h1:RUy1O5Ly4tAaQDDpahds8z+4uewwsXg6SNCH0hYm7pE= -github.com/nyaruka/gocommon v1.33.1/go.mod h1:gusIA2aNC8EPB3ozlP4O0PaBiHUNq5+f1peRNvcn0DI= +github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/nyaruka/gocommon v1.34.0 h1:efIqt2ZlN4WAvXylId/sNnNSOlgo4oGxSJLNLg2W21c= +github.com/nyaruka/gocommon v1.34.0/go.mod h1:gusIA2aNC8EPB3ozlP4O0PaBiHUNq5+f1peRNvcn0DI= github.com/nyaruka/phonenumbers v1.1.4 h1:de8exybd7+g9q+gXP04Ypt9ijFYXXm8wrgqPf+Ckk20= github.com/nyaruka/phonenumbers v1.1.4/go.mod h1:yShPJHDSH3aTKzCbXyVxNpbl2kA+F+Ne5Pun/MvFRos= github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=