Add zeronull package for easier NULL <-> zero conversion

non-blocking
Jack Christensen 2020-01-24 11:23:28 -06:00
parent 186f4b3539
commit 0bbaad1348
16 changed files with 977 additions and 0 deletions

View File

@ -284,3 +284,153 @@ func TestDatabaseSQLSuccessfulNormalizeEqFunc(t testing.TB, driverName string, t
}
}
}
func TestGoZeroToNullConversion(t testing.TB, pgTypeName string, zero interface{}) {
TestPgxGoZeroToNullConversion(t, pgTypeName, zero)
for _, driverName := range []string{"github.com/lib/pq", "github.com/jackc/pgx/stdlib"} {
TestDatabaseSQLGoZeroToNullConversion(t, driverName, pgTypeName, zero)
}
}
func TestNullToGoZeroConversion(t testing.TB, pgTypeName string, zero interface{}) {
TestPgxNullToGoZeroConversion(t, pgTypeName, zero)
for _, driverName := range []string{"github.com/lib/pq", "github.com/jackc/pgx/stdlib"} {
TestDatabaseSQLNullToGoZeroConversion(t, driverName, pgTypeName, zero)
}
}
func TestPgxGoZeroToNullConversion(t testing.TB, pgTypeName string, zero interface{}) {
conn := MustConnectPgx(t)
defer MustCloseContext(t, conn)
_, err := conn.Prepare(context.Background(), "test", fmt.Sprintf("select $1::%s is null", pgTypeName))
if err != nil {
t.Fatal(err)
}
formats := []struct {
name string
formatCode int16
}{
{name: "TextFormat", formatCode: pgx.TextFormatCode},
{name: "BinaryFormat", formatCode: pgx.BinaryFormatCode},
}
for _, paramFormat := range formats {
vEncoder := ForceEncoder(zero, paramFormat.formatCode)
if vEncoder == nil {
t.Logf("Skipping Param %s: %#v does not implement %v for encoding", paramFormat.name, zero, paramFormat.name)
continue
}
var result bool
err := conn.QueryRow(context.Background(), "test", vEncoder).Scan(&result)
if err != nil {
t.Errorf("Param %s: %v", paramFormat.name, err)
}
if !result {
t.Errorf("Param %s: did not convert zero to null", paramFormat.name)
}
}
}
func TestPgxNullToGoZeroConversion(t testing.TB, pgTypeName string, zero interface{}) {
conn := MustConnectPgx(t)
defer MustCloseContext(t, conn)
_, err := conn.Prepare(context.Background(), "test", fmt.Sprintf("select null::%s", pgTypeName))
if err != nil {
t.Fatal(err)
}
formats := []struct {
name string
formatCode int16
}{
{name: "TextFormat", formatCode: pgx.TextFormatCode},
{name: "BinaryFormat", formatCode: pgx.BinaryFormatCode},
}
for _, resultFormat := range formats {
switch resultFormat.formatCode {
case pgx.TextFormatCode:
if _, ok := zero.(pgtype.TextEncoder); !ok {
t.Logf("Skipping Result %s: %#v does not implement %v for decoding", resultFormat.name, zero, resultFormat.name)
continue
}
case pgx.BinaryFormatCode:
if _, ok := zero.(pgtype.BinaryEncoder); !ok {
t.Logf("Skipping Result %s: %#v does not implement %v for decoding", resultFormat.name, zero, resultFormat.name)
continue
}
}
// Derefence value if it is a pointer
derefZero := zero
refVal := reflect.ValueOf(zero)
if refVal.Kind() == reflect.Ptr {
derefZero = refVal.Elem().Interface()
}
result := reflect.New(reflect.TypeOf(derefZero))
err := conn.QueryRow(context.Background(), "test").Scan(result.Interface())
if err != nil {
t.Errorf("Result %s: %v", resultFormat.name, err)
}
if !reflect.DeepEqual(result.Elem().Interface(), derefZero) {
t.Errorf("Result %s: did not convert null to zero", resultFormat.name)
}
}
}
func TestDatabaseSQLGoZeroToNullConversion(t testing.TB, driverName, pgTypeName string, zero interface{}) {
conn := MustConnectDatabaseSQL(t, driverName)
defer MustClose(t, conn)
ps, err := conn.Prepare(fmt.Sprintf("select $1::%s is null", pgTypeName))
if err != nil {
t.Fatal(err)
}
var result bool
err = ps.QueryRow(zero).Scan(&result)
if err != nil {
t.Errorf("%v %v", driverName, err)
}
if !result {
t.Errorf("%v: did not convert zero to null", driverName)
}
}
func TestDatabaseSQLNullToGoZeroConversion(t testing.TB, driverName, pgTypeName string, zero interface{}) {
conn := MustConnectDatabaseSQL(t, driverName)
defer MustClose(t, conn)
ps, err := conn.Prepare(fmt.Sprintf("select null::%s", pgTypeName))
if err != nil {
t.Fatal(err)
}
// Derefence value if it is a pointer
derefZero := zero
refVal := reflect.ValueOf(zero)
if refVal.Kind() == reflect.Ptr {
derefZero = refVal.Elem().Interface()
}
result := reflect.New(reflect.TypeOf(derefZero))
err = ps.QueryRow().Scan(result.Interface())
if err != nil {
t.Errorf("%v %v", driverName, err)
}
if !reflect.DeepEqual(result.Elem().Interface(), derefZero) {
t.Errorf("%s: did not convert null to zero", driverName)
}
}

22
zeronull/doc.go Normal file
View File

@ -0,0 +1,22 @@
// Package zeronull contains types that automatically convert between database NULLs and Go zero values.
/*
Sometimes the distinction between a zero value and a NULL value is not useful at the application level. For example,
in PostgreSQL an empty string may be stored as NULL. There is usually no application level distinction between an
empty string and a NULL string. Package zeronull implements types that seemlessly convert between PostgreSQL NULL and
the zero value.
It is recommended to convert types at usage time rather than instantiate these types directly. In the example below,
middlename would be stored as a NULL.
firstname := "John"
middlename := ""
lastname := "Smith"
_, err := conn.Exec(
ctx,
"insert into people(firstname, middlename, lastname) values($1, $2, $3)",
zeronull.Text(firstname),
zeronull.Text(middlename),
zeronull.Text(lastname),
)
*/
package zeronull

90
zeronull/int2.go Normal file
View File

@ -0,0 +1,90 @@
package zeronull
import (
"database/sql/driver"
"github.com/jackc/pgtype"
)
type Int2 int16
func (dst *Int2) DecodeText(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Int2
err := nullable.DecodeText(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Int2(nullable.Int)
} else {
*dst = 0
}
return nil
}
func (dst *Int2) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Int2
err := nullable.DecodeBinary(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Int2(nullable.Int)
} else {
*dst = 0
}
return nil
}
func (src Int2) EncodeText(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if src == 0 {
return nil, nil
}
nullable := pgtype.Int2{
Int: int16(src),
Status: pgtype.Present,
}
return nullable.EncodeText(ci, buf)
}
func (src Int2) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if src == 0 {
return nil, nil
}
nullable := pgtype.Int2{
Int: int16(src),
Status: pgtype.Present,
}
return nullable.EncodeBinary(ci, buf)
}
// Scan implements the database/sql Scanner interface.
func (dst *Int2) Scan(src interface{}) error {
if src == nil {
*dst = 0
return nil
}
var nullable pgtype.Int2
err := nullable.Scan(src)
if err != nil {
return err
}
*dst = Int2(nullable.Int)
return nil
}
// Value implements the database/sql/driver Valuer interface.
func (src Int2) Value() (driver.Value, error) {
return pgtype.EncodeValueText(src)
}

23
zeronull/int2_test.go Normal file
View File

@ -0,0 +1,23 @@
package zeronull_test
import (
"testing"
"github.com/jackc/pgtype/testutil"
"github.com/jackc/pgtype/zeronull"
)
func TestInt2Transcode(t *testing.T) {
testutil.TestSuccessfulTranscode(t, "int2", []interface{}{
(zeronull.Int2)(1),
(zeronull.Int2)(0),
})
}
func TestInt2ConvertsGoZeroToNull(t *testing.T) {
testutil.TestGoZeroToNullConversion(t, "int2", (zeronull.Int2)(0))
}
func TestInt2ConvertsNullToGoZero(t *testing.T) {
testutil.TestNullToGoZeroConversion(t, "int2", (zeronull.Int2)(0))
}

90
zeronull/int4.go Normal file
View File

@ -0,0 +1,90 @@
package zeronull
import (
"database/sql/driver"
"github.com/jackc/pgtype"
)
type Int4 int32
func (dst *Int4) DecodeText(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Int4
err := nullable.DecodeText(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Int4(nullable.Int)
} else {
*dst = 0
}
return nil
}
func (dst *Int4) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Int4
err := nullable.DecodeBinary(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Int4(nullable.Int)
} else {
*dst = 0
}
return nil
}
func (src Int4) EncodeText(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if src == 0 {
return nil, nil
}
nullable := pgtype.Int4{
Int: int32(src),
Status: pgtype.Present,
}
return nullable.EncodeText(ci, buf)
}
func (src Int4) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if src == 0 {
return nil, nil
}
nullable := pgtype.Int4{
Int: int32(src),
Status: pgtype.Present,
}
return nullable.EncodeBinary(ci, buf)
}
// Scan implements the database/sql Scanner interface.
func (dst *Int4) Scan(src interface{}) error {
if src == nil {
*dst = 0
return nil
}
var nullable pgtype.Int4
err := nullable.Scan(src)
if err != nil {
return err
}
*dst = Int4(nullable.Int)
return nil
}
// Value implements the database/sql/driver Valuer interface.
func (src Int4) Value() (driver.Value, error) {
return pgtype.EncodeValueText(src)
}

23
zeronull/int4_test.go Normal file
View File

@ -0,0 +1,23 @@
package zeronull_test
import (
"testing"
"github.com/jackc/pgtype/testutil"
"github.com/jackc/pgtype/zeronull"
)
func TestInt4Transcode(t *testing.T) {
testutil.TestSuccessfulTranscode(t, "int4", []interface{}{
(zeronull.Int4)(1),
(zeronull.Int4)(0),
})
}
func TestInt4ConvertsGoZeroToNull(t *testing.T) {
testutil.TestGoZeroToNullConversion(t, "int4", (zeronull.Int4)(0))
}
func TestInt4ConvertsNullToGoZero(t *testing.T) {
testutil.TestNullToGoZeroConversion(t, "int4", (zeronull.Int4)(0))
}

90
zeronull/int8.go Normal file
View File

@ -0,0 +1,90 @@
package zeronull
import (
"database/sql/driver"
"github.com/jackc/pgtype"
)
type Int8 int64
func (dst *Int8) DecodeText(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Int8
err := nullable.DecodeText(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Int8(nullable.Int)
} else {
*dst = 0
}
return nil
}
func (dst *Int8) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Int8
err := nullable.DecodeBinary(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Int8(nullable.Int)
} else {
*dst = 0
}
return nil
}
func (src Int8) EncodeText(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if src == 0 {
return nil, nil
}
nullable := pgtype.Int8{
Int: int64(src),
Status: pgtype.Present,
}
return nullable.EncodeText(ci, buf)
}
func (src Int8) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if src == 0 {
return nil, nil
}
nullable := pgtype.Int8{
Int: int64(src),
Status: pgtype.Present,
}
return nullable.EncodeBinary(ci, buf)
}
// Scan implements the database/sql Scanner interface.
func (dst *Int8) Scan(src interface{}) error {
if src == nil {
*dst = 0
return nil
}
var nullable pgtype.Int8
err := nullable.Scan(src)
if err != nil {
return err
}
*dst = Int8(nullable.Int)
return nil
}
// Value implements the database/sql/driver Valuer interface.
func (src Int8) Value() (driver.Value, error) {
return pgtype.EncodeValueText(src)
}

23
zeronull/int8_test.go Normal file
View File

@ -0,0 +1,23 @@
package zeronull_test
import (
"testing"
"github.com/jackc/pgtype/testutil"
"github.com/jackc/pgtype/zeronull"
)
func TestInt8Transcode(t *testing.T) {
testutil.TestSuccessfulTranscode(t, "int8", []interface{}{
(zeronull.Int8)(1),
(zeronull.Int8)(0),
})
}
func TestInt8ConvertsGoZeroToNull(t *testing.T) {
testutil.TestGoZeroToNullConversion(t, "int8", (zeronull.Int8)(0))
}
func TestInt8ConvertsNullToGoZero(t *testing.T) {
testutil.TestNullToGoZeroConversion(t, "int8", (zeronull.Int8)(0))
}

90
zeronull/text.go Normal file
View File

@ -0,0 +1,90 @@
package zeronull
import (
"database/sql/driver"
"github.com/jackc/pgtype"
)
type Text string
func (dst *Text) DecodeText(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Text
err := nullable.DecodeText(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Text(nullable.String)
} else {
*dst = Text("")
}
return nil
}
func (dst *Text) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Text
err := nullable.DecodeBinary(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Text(nullable.String)
} else {
*dst = Text("")
}
return nil
}
func (src Text) EncodeText(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if src == Text("") {
return nil, nil
}
nullable := pgtype.Text{
String: string(src),
Status: pgtype.Present,
}
return nullable.EncodeText(ci, buf)
}
func (src Text) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if src == Text("") {
return nil, nil
}
nullable := pgtype.Text{
String: string(src),
Status: pgtype.Present,
}
return nullable.EncodeBinary(ci, buf)
}
// Scan implements the database/sql Scanner interface.
func (dst *Text) Scan(src interface{}) error {
if src == nil {
*dst = Text("")
return nil
}
var nullable pgtype.Text
err := nullable.Scan(src)
if err != nil {
return err
}
*dst = Text(nullable.String)
return nil
}
// Value implements the database/sql/driver Valuer interface.
func (src Text) Value() (driver.Value, error) {
return pgtype.EncodeValueText(src)
}

23
zeronull/text_test.go Normal file
View File

@ -0,0 +1,23 @@
package zeronull_test
import (
"testing"
"github.com/jackc/pgtype/testutil"
"github.com/jackc/pgtype/zeronull"
)
func TestTextTranscode(t *testing.T) {
testutil.TestSuccessfulTranscode(t, "text", []interface{}{
(zeronull.Text)("foo"),
(zeronull.Text)(""),
})
}
func TestTextConvertsGoZeroToNull(t *testing.T) {
testutil.TestGoZeroToNullConversion(t, "text", (zeronull.Text)(""))
}
func TestTextConvertsNullToGoZero(t *testing.T) {
testutil.TestNullToGoZeroConversion(t, "text", (zeronull.Text)(""))
}

91
zeronull/timestamp.go Normal file
View File

@ -0,0 +1,91 @@
package zeronull
import (
"database/sql/driver"
"time"
"github.com/jackc/pgtype"
)
type Timestamp time.Time
func (dst *Timestamp) DecodeText(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Timestamp
err := nullable.DecodeText(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Timestamp(nullable.Time)
} else {
*dst = Timestamp{}
}
return nil
}
func (dst *Timestamp) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Timestamp
err := nullable.DecodeBinary(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Timestamp(nullable.Time)
} else {
*dst = Timestamp{}
}
return nil
}
func (src Timestamp) EncodeText(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if (src == Timestamp{}) {
return nil, nil
}
nullable := pgtype.Timestamp{
Time: time.Time(src),
Status: pgtype.Present,
}
return nullable.EncodeText(ci, buf)
}
func (src Timestamp) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if (src == Timestamp{}) {
return nil, nil
}
nullable := pgtype.Timestamp{
Time: time.Time(src),
Status: pgtype.Present,
}
return nullable.EncodeBinary(ci, buf)
}
// Scan implements the database/sql Scanner interface.
func (dst *Timestamp) Scan(src interface{}) error {
if src == nil {
*dst = Timestamp{}
return nil
}
var nullable pgtype.Timestamp
err := nullable.Scan(src)
if err != nil {
return err
}
*dst = Timestamp(nullable.Time)
return nil
}
// Value implements the database/sql/driver Valuer interface.
func (src Timestamp) Value() (driver.Value, error) {
return pgtype.EncodeValueText(src)
}

View File

@ -0,0 +1,29 @@
package zeronull_test
import (
"testing"
"time"
"github.com/jackc/pgtype/testutil"
"github.com/jackc/pgtype/zeronull"
)
func TestTimestampTranscode(t *testing.T) {
testutil.TestSuccessfulTranscodeEqFunc(t, "timestamp", []interface{}{
(zeronull.Timestamp)(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
(zeronull.Timestamp)(time.Time{}),
}, func(a, b interface{}) bool {
at := a.(zeronull.Timestamp)
bt := b.(zeronull.Timestamp)
return time.Time(at).Equal(time.Time(bt))
})
}
func TestTimestampConvertsGoZeroToNull(t *testing.T) {
testutil.TestGoZeroToNullConversion(t, "timestamp", (zeronull.Timestamp)(time.Time{}))
}
func TestTimestampConvertsNullToGoZero(t *testing.T) {
testutil.TestNullToGoZeroConversion(t, "timestamp", (zeronull.Timestamp)(time.Time{}))
}

91
zeronull/timestamptz.go Normal file
View File

@ -0,0 +1,91 @@
package zeronull
import (
"database/sql/driver"
"time"
"github.com/jackc/pgtype"
)
type Timestamptz time.Time
func (dst *Timestamptz) DecodeText(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Timestamptz
err := nullable.DecodeText(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Timestamptz(nullable.Time)
} else {
*dst = Timestamptz{}
}
return nil
}
func (dst *Timestamptz) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.Timestamptz
err := nullable.DecodeBinary(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = Timestamptz(nullable.Time)
} else {
*dst = Timestamptz{}
}
return nil
}
func (src Timestamptz) EncodeText(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if (src == Timestamptz{}) {
return nil, nil
}
nullable := pgtype.Timestamptz{
Time: time.Time(src),
Status: pgtype.Present,
}
return nullable.EncodeText(ci, buf)
}
func (src Timestamptz) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if (src == Timestamptz{}) {
return nil, nil
}
nullable := pgtype.Timestamptz{
Time: time.Time(src),
Status: pgtype.Present,
}
return nullable.EncodeBinary(ci, buf)
}
// Scan implements the database/sql Scanner interface.
func (dst *Timestamptz) Scan(src interface{}) error {
if src == nil {
*dst = Timestamptz{}
return nil
}
var nullable pgtype.Timestamptz
err := nullable.Scan(src)
if err != nil {
return err
}
*dst = Timestamptz(nullable.Time)
return nil
}
// Value implements the database/sql/driver Valuer interface.
func (src Timestamptz) Value() (driver.Value, error) {
return pgtype.EncodeValueText(src)
}

View File

@ -0,0 +1,29 @@
package zeronull_test
import (
"testing"
"time"
"github.com/jackc/pgtype/testutil"
"github.com/jackc/pgtype/zeronull"
)
func TestTimestamptzTranscode(t *testing.T) {
testutil.TestSuccessfulTranscodeEqFunc(t, "timestamptz", []interface{}{
(zeronull.Timestamptz)(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
(zeronull.Timestamptz)(time.Time{}),
}, func(a, b interface{}) bool {
at := a.(zeronull.Timestamptz)
bt := b.(zeronull.Timestamptz)
return time.Time(at).Equal(time.Time(bt))
})
}
func TestTimestamptzConvertsGoZeroToNull(t *testing.T) {
testutil.TestGoZeroToNullConversion(t, "timestamptz", (zeronull.Timestamptz)(time.Time{}))
}
func TestTimestamptzConvertsNullToGoZero(t *testing.T) {
testutil.TestNullToGoZeroConversion(t, "timestamptz", (zeronull.Timestamptz)(time.Time{}))
}

90
zeronull/uuid.go Normal file
View File

@ -0,0 +1,90 @@
package zeronull
import (
"database/sql/driver"
"github.com/jackc/pgtype"
)
type UUID [16]byte
func (dst *UUID) DecodeText(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.UUID
err := nullable.DecodeText(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = UUID(nullable.Bytes)
} else {
*dst = UUID{}
}
return nil
}
func (dst *UUID) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
var nullable pgtype.UUID
err := nullable.DecodeBinary(ci, src)
if err != nil {
return err
}
if nullable.Status == pgtype.Present {
*dst = UUID(nullable.Bytes)
} else {
*dst = UUID{}
}
return nil
}
func (src UUID) EncodeText(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if (src == UUID{}) {
return nil, nil
}
nullable := pgtype.UUID{
Bytes: [16]byte(src),
Status: pgtype.Present,
}
return nullable.EncodeText(ci, buf)
}
func (src UUID) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) {
if (src == UUID{}) {
return nil, nil
}
nullable := pgtype.UUID{
Bytes: [16]byte(src),
Status: pgtype.Present,
}
return nullable.EncodeBinary(ci, buf)
}
// Scan implements the database/sql Scanner interface.
func (dst *UUID) Scan(src interface{}) error {
if src == nil {
*dst = UUID{}
return nil
}
var nullable pgtype.UUID
err := nullable.Scan(src)
if err != nil {
return err
}
*dst = UUID(nullable.Bytes)
return nil
}
// Value implements the database/sql/driver Valuer interface.
func (src UUID) Value() (driver.Value, error) {
return pgtype.EncodeValueText(src)
}

23
zeronull/uuid_test.go Normal file
View File

@ -0,0 +1,23 @@
package zeronull_test
import (
"testing"
"github.com/jackc/pgtype/testutil"
"github.com/jackc/pgtype/zeronull"
)
func TestUUIDTranscode(t *testing.T) {
testutil.TestSuccessfulTranscode(t, "uuid", []interface{}{
(*zeronull.UUID)(&[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}),
(*zeronull.UUID)(&[16]byte{}),
})
}
func TestUUIDConvertsGoZeroToNull(t *testing.T) {
testutil.TestGoZeroToNullConversion(t, "uuid", (*zeronull.UUID)(&[16]byte{}))
}
func TestUUIDConvertsNullToGoZero(t *testing.T) {
testutil.TestNullToGoZeroConversion(t, "uuid", (*zeronull.UUID)(&[16]byte{}))
}