...

Source file src/github.com/jackc/pgtype/custom_composite_test.go

Documentation: github.com/jackc/pgtype

     1  package pgtype_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"os"
     8  
     9  	"github.com/jackc/pgtype"
    10  	pgx "github.com/jackc/pgx/v4"
    11  )
    12  
    13  type MyType struct {
    14  	a int32   // NULL will cause decoding error
    15  	b *string // there can be NULL in this position in SQL
    16  }
    17  
    18  func (dst *MyType) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
    19  	if src == nil {
    20  		return errors.New("NULL values can't be decoded. Scan into a &*MyType to handle NULLs")
    21  	}
    22  
    23  	if err := (pgtype.CompositeFields{&dst.a, &dst.b}).DecodeBinary(ci, src); err != nil {
    24  		return err
    25  	}
    26  
    27  	return nil
    28  }
    29  
    30  func (src MyType) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) (newBuf []byte, err error) {
    31  	a := pgtype.Int4{src.a, pgtype.Present}
    32  	var b pgtype.Text
    33  	if src.b != nil {
    34  		b = pgtype.Text{*src.b, pgtype.Present}
    35  	} else {
    36  		b = pgtype.Text{Status: pgtype.Null}
    37  	}
    38  
    39  	return (pgtype.CompositeFields{&a, &b}).EncodeBinary(ci, buf)
    40  }
    41  
    42  func ptrS(s string) *string {
    43  	return &s
    44  }
    45  
    46  func E(err error) {
    47  	if err != nil {
    48  		panic(err)
    49  	}
    50  }
    51  
    52  // ExampleCustomCompositeTypes demonstrates how support for custom types mappable to SQL
    53  // composites can be added.
    54  func Example_customCompositeTypes() {
    55  	conn, err := pgx.Connect(context.Background(), os.Getenv("PGX_TEST_DATABASE"))
    56  	E(err)
    57  
    58  	defer conn.Close(context.Background())
    59  	_, err = conn.Exec(context.Background(), `drop type if exists mytype;
    60  
    61  create type mytype as (
    62    a int4,
    63    b text
    64  );`)
    65  	E(err)
    66  	defer conn.Exec(context.Background(), "drop type mytype")
    67  
    68  	var result *MyType
    69  
    70  	// Demonstrates both passing and reading back composite values
    71  	err = conn.QueryRow(context.Background(), "select $1::mytype",
    72  		pgx.QueryResultFormats{pgx.BinaryFormatCode}, MyType{1, ptrS("foo")}).
    73  		Scan(&result)
    74  	E(err)
    75  
    76  	fmt.Printf("First row: a=%d b=%s\n", result.a, *result.b)
    77  
    78  	// Because we scan into &*MyType, NULLs are handled generically by assigning nil to result
    79  	err = conn.QueryRow(context.Background(), "select NULL::mytype", pgx.QueryResultFormats{pgx.BinaryFormatCode}).Scan(&result)
    80  	E(err)
    81  
    82  	fmt.Printf("Second row: %v\n", result)
    83  
    84  	// Output:
    85  	// First row: a=1 b=foo
    86  	// Second row: <nil>
    87  }
    88  

View as plain text