diff --git a/SHOULDERS.md b/SHOULDERS.md index a9c00ef1..f035f86e 100644 --- a/SHOULDERS.md +++ b/SHOULDERS.md @@ -37,16 +37,9 @@ Thank you to the following **GIANTS**: * [github.com/inconshreveable/mousetrap](https://godoc.org/github.com/inconshreveable/mousetrap) * [github.com/jackc/chunkreader](https://godoc.org/github.com/jackc/chunkreader) * [github.com/jackc/chunkreader/v2](https://godoc.org/github.com/jackc/chunkreader/v2) -* [github.com/jackc/pgconn](https://godoc.org/github.com/jackc/pgconn) -* [github.com/jackc/pgio](https://godoc.org/github.com/jackc/pgio) -* [github.com/jackc/pgmock](https://godoc.org/github.com/jackc/pgmock) * [github.com/jackc/pgpassfile](https://godoc.org/github.com/jackc/pgpassfile) -* [github.com/jackc/pgproto3](https://godoc.org/github.com/jackc/pgproto3) -* [github.com/jackc/pgproto3/v2](https://godoc.org/github.com/jackc/pgproto3/v2) * [github.com/jackc/pgservicefile](https://godoc.org/github.com/jackc/pgservicefile) -* [github.com/jackc/pgtype](https://godoc.org/github.com/jackc/pgtype) -* [github.com/jackc/pgx/v4](https://godoc.org/github.com/jackc/pgx/v4) -* [github.com/jackc/puddle](https://godoc.org/github.com/jackc/puddle) +* [github.com/jackc/pgx/v5](https://godoc.org/github.com/jackc/pgx/v5) * [github.com/jmoiron/sqlx](https://godoc.org/github.com/jmoiron/sqlx) * [github.com/joho/godotenv](https://godoc.org/github.com/joho/godotenv) * [github.com/kballard/go-shellquote](https://godoc.org/github.com/kballard/go-shellquote) diff --git a/executors_test.go b/executors_test.go index e0d4ccaf..eb312138 100644 --- a/executors_test.go +++ b/executors_test.go @@ -1605,6 +1605,8 @@ func Test_UpdateQuery(t *testing.T) { // ID is ignored count, err = tx.Where("true").UpdateQuery(&User{ID: 123, Name: nulls.NewString("Bar")}, "id", "name") + r.NoError(err) + r.Equal(int64(3), count) r.NoError(tx.Find(u1b, u1.ID)) r.NoError(tx.Find(u2b, u2.ID)) r.NoError(tx.Find(u3b, u3.ID)) @@ -1613,7 +1615,7 @@ func Test_UpdateQuery(t *testing.T) { r.Equal(u3b.Name.String, "Bar") // Invalid column yields an error - count, err = tx.Where("name = ?", "Foo").UpdateQuery(&User{Name: nulls.NewString("Bar")}, "mistake") + _, err = tx.Where("name = ?", "Foo").UpdateQuery(&User{Name: nulls.NewString("Bar")}, "mistake") r.Contains(err.Error(), "could not find name mistake") tx.Where("true").Delete(&User{}) diff --git a/slices/float.go b/slices/float.go index 18dfa130..3420b2ef 100644 --- a/slices/float.go +++ b/slices/float.go @@ -20,6 +20,9 @@ func (f Float) Interface() interface{} { func (f *Float) Scan(src interface{}) error { var str string switch t := src.(type) { + case nil: + *f = make([]float64, 0) + return nil case []byte: str = string(t) case string: diff --git a/slices/int.go b/slices/int.go index e800fcbd..4d953b06 100644 --- a/slices/int.go +++ b/slices/int.go @@ -20,6 +20,9 @@ func (i Int) Interface() interface{} { func (i *Int) Scan(src interface{}) error { var str string switch t := src.(type) { + case nil: + *i = make([]int, 0) + return nil case []byte: str = string(t) case string: diff --git a/slices/string.go b/slices/string.go index 308f1ba0..0f033be0 100644 --- a/slices/string.go +++ b/slices/string.go @@ -24,6 +24,10 @@ func (s String) Interface() interface{} { // Scan implements the sql.Scanner interface. // It allows to read the string slice from the database value. func (s *String) Scan(src interface{}) error { + if src == nil { + *s = make([]string, 0) + return nil + } // Still relying on pq driver to help with string arrays. ss := pq.StringArray(*s) err := ss.Scan(src) diff --git a/slices/string_test.go b/slices/string_test.go index a2ba2519..8bcf36be 100644 --- a/slices/string_test.go +++ b/slices/string_test.go @@ -8,6 +8,14 @@ import ( ) func Test_String_Scan(t *testing.T) { + t.Run("empty slice", func(t *testing.T) { + r := require.New(t) + in := "{}" + v := &String{} + r.NoError(v.Scan(in)) + r.Len(*v, 0) + }) + r := require.New(t) in := `{"This has a comma,","This has a double quote\"","Also a single'"}` s := &String{} diff --git a/slices/uuid.go b/slices/uuid.go index 8fdc2222..94ce58b3 100644 --- a/slices/uuid.go +++ b/slices/uuid.go @@ -24,6 +24,9 @@ func (s UUID) Interface() interface{} { func (s *UUID) Scan(src interface{}) error { var b []byte switch t := src.(type) { + case nil: + *s = make([]uuid.UUID, 0) + return nil case []byte: b = t case string: diff --git a/slices_test.go b/slices_test.go index 83e63ed0..3148c3d3 100644 --- a/slices_test.go +++ b/slices_test.go @@ -11,6 +11,8 @@ type Cake struct { Int slices.Int `db:"int_slice"` Float slices.Float `db:"float_slice"` String slices.String `db:"string_slice"` + UUID slices.UUID `db:"uuid_slice"` + Map slices.Map `db:"map"` CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` } @@ -27,7 +29,10 @@ func (s *PostgreSQLSuite) Test_String() { err = tx.Reload(c) r.NoError(err) + r.Equal(slices.Int{}, c.Int) + r.Equal(slices.Float{}, c.Float) r.Equal(slices.String{"a", "b", "c"}, c.String) + r.Equal(slices.UUID{}, c.UUID) }) } @@ -45,6 +50,8 @@ func (s *PostgreSQLSuite) Test_Int() { r.NoError(err) r.Equal(slices.Int{1, 2, 3}, c.Int) r.Equal(slices.Float{}, c.Float) + r.Equal(slices.String{}, c.String) + r.Equal(slices.UUID{}, c.UUID) }) } @@ -62,5 +69,7 @@ func (s *PostgreSQLSuite) Test_Float() { r.NoError(err) r.Equal(slices.Int{}, c.Int) r.Equal(slices.Float{1.0, 2.1, 3.2}, c.Float) + r.Equal(slices.String{}, c.String) + r.Equal(slices.UUID{}, c.UUID) }) } diff --git a/testdata/migrations/20181104140743_cakes.up.fizz b/testdata/migrations/20181104140743_cakes.up.fizz index 2397ab40..847c7274 100644 --- a/testdata/migrations/20181104140743_cakes.up.fizz +++ b/testdata/migrations/20181104140743_cakes.up.fizz @@ -4,6 +4,8 @@ t.Column("int_slice", "int[]", {"null": true}) t.Column("float_slice", "numeric[]", {"null": true}) t.Column("string_slice", "varchar[]", {"null": true}) + t.Column("uuid_slice", "uuid[]", {"null": true}) + t.Column("map", "json", {"null": true}) t.Timestamps() } -{{ end -}} \ No newline at end of file +{{ end -}}