2
0

add RowTo(AddrOf)StructByNameLax

This commit is contained in:
Audi P. Risa P
2023-03-24 17:11:49 +07:00
committed by Jack Christensen
parent e9d64ec29d
commit 193bab416f
2 changed files with 250 additions and 1 deletions
+161
View File
@@ -635,3 +635,164 @@ insert into products (name, price) values
// Fries: $5
// Soft Drink: $3
}
func TestRowToStructByNameLax(t *testing.T) {
type person struct {
Last string
First string
Age int32
Ignore bool `db:"-"`
}
defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
rows, _ := conn.Query(ctx, `select 'John' as first, 'Smith' as last, n as age from generate_series(0, 9) n`)
slice, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[person])
assert.NoError(t, err)
assert.Len(t, slice, 10)
for i := range slice {
assert.Equal(t, "Smith", slice[i].Last)
assert.Equal(t, "John", slice[i].First)
assert.EqualValues(t, i, slice[i].Age)
}
// check missing fields in a returned row
rows, _ = conn.Query(ctx, `select 'John' as first, n as age from generate_series(0, 9) n`)
slice, err = pgx.CollectRows(rows, pgx.RowToStructByNameLax[person])
assert.NoError(t, err)
assert.Len(t, slice, 10)
for i := range slice {
assert.Equal(t, "John", slice[i].First)
assert.EqualValues(t, i, slice[i].Age)
}
// check extra fields in a returned row
rows, _ = conn.Query(ctx, `select 'John' as first, 'Smith' as last, n as age, null as ignore from generate_series(0, 9) n`)
_, err = pgx.CollectRows(rows, pgx.RowToAddrOfStructByNameLax[person])
assert.ErrorContains(t, err, "struct doesn't have corresponding row field ignore")
// check missing fields in a destination struct
rows, _ = conn.Query(ctx, `select 'Smith' as last, 'D.' as middle, n as age from generate_series(0, 9) n`)
_, err = pgx.CollectRows(rows, pgx.RowToAddrOfStructByNameLax[person])
assert.ErrorContains(t, err, "struct doesn't have corresponding row field middle")
// check ignored fields in a destination struct
rows, _ = conn.Query(ctx, `select 'Smith' as last, n as age, null as ignore from generate_series(0, 9) n`)
_, err = pgx.CollectRows(rows, pgx.RowToAddrOfStructByNameLax[person])
assert.ErrorContains(t, err, "struct doesn't have corresponding row field ignore")
})
}
func TestRowToStructByNameLaxEmbeddedStruct(t *testing.T) {
type Name struct {
Last string `db:"last_name"`
First string `db:"first_name"`
}
type person struct {
Ignore bool `db:"-"`
Name
Age int32
}
defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
rows, _ := conn.Query(ctx, `select 'John' as first_name, 'Smith' as last_name, n as age from generate_series(0, 9) n`)
slice, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[person])
assert.NoError(t, err)
assert.Len(t, slice, 10)
for i := range slice {
assert.Equal(t, "Smith", slice[i].Name.Last)
assert.Equal(t, "John", slice[i].Name.First)
assert.EqualValues(t, i, slice[i].Age)
}
// check missing fields in a returned row
rows, _ = conn.Query(ctx, `select 'John' as first_name, n as age from generate_series(0, 9) n`)
slice, err = pgx.CollectRows(rows, pgx.RowToStructByNameLax[person])
assert.NoError(t, err)
assert.Len(t, slice, 10)
for i := range slice {
assert.Equal(t, "John", slice[i].Name.First)
assert.EqualValues(t, i, slice[i].Age)
}
// check extra fields in a returned row
rows, _ = conn.Query(ctx, `select 'John' as first_name, 'Smith' as last_name, n as age, null as ignore from generate_series(0, 9) n`)
_, err = pgx.CollectRows(rows, pgx.RowToAddrOfStructByNameLax[person])
assert.ErrorContains(t, err, "struct doesn't have corresponding row field ignore")
// check missing fields in a destination struct
rows, _ = conn.Query(ctx, `select 'Smith' as last_name, 'D.' as middle_name, n as age from generate_series(0, 9) n`)
_, err = pgx.CollectRows(rows, pgx.RowToAddrOfStructByNameLax[person])
assert.ErrorContains(t, err, "struct doesn't have corresponding row field middle_name")
// check ignored fields in a destination struct
rows, _ = conn.Query(ctx, `select 'Smith' as last_name, n as age, null as ignore from generate_series(0, 9) n`)
_, err = pgx.CollectRows(rows, pgx.RowToAddrOfStructByNameLax[person])
assert.ErrorContains(t, err, "struct doesn't have corresponding row field ignore")
})
}
func ExampleRowToStructByNameLax() {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
conn, err := pgx.Connect(ctx, os.Getenv("PGX_TEST_DATABASE"))
if err != nil {
fmt.Printf("Unable to establish connection: %v", err)
return
}
if conn.PgConn().ParameterStatus("crdb_version") != "" {
// Skip test / example when running on CockroachDB. Since an example can't be skipped fake success instead.
fmt.Println(`Cheeseburger: $10
Fries: $5
Soft Drink: $3`)
return
}
// Setup example schema and data.
_, err = conn.Exec(ctx, `
create temporary table products (
id int primary key generated by default as identity,
name varchar(100) not null,
price int not null
);
insert into products (name, price) values
('Cheeseburger', 10),
('Double Cheeseburger', 14),
('Fries', 5),
('Soft Drink', 3);
`)
if err != nil {
fmt.Printf("Unable to setup example schema and data: %v", err)
return
}
type product struct {
ID int32
Name string
Type string
Price int32
}
rows, _ := conn.Query(ctx, "select * from products where price < $1 order by price desc", 12)
products, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[product])
if err != nil {
fmt.Printf("CollectRows error: %v", err)
return
}
for _, p := range products {
fmt.Printf("%s: $%d\n", p.Name, p.Price)
}
// Output:
// Cheeseburger: $10
// Fries: $5
// Soft Drink: $3
}