Add child records docs and examples

pull/1281/head
Jack Christensen 2022-07-23 10:11:13 -05:00
parent 4739f79fca
commit 5cee04a026
4 changed files with 97 additions and 2 deletions

View File

@ -112,6 +112,11 @@ Compatibility with database/sql
pgtype also includes support for custom types implementing the database/sql.Scanner and database/sql/driver.Valuer
interfaces.
Child Records
pgtype's support for arrays and composite records can be used to load records and their children in a single query. See
example_child_records_test.go for an example.
Overview of Scanning Implementation
The first step is to use the OID to lookup the correct Codec. If the OID is unavailable, Map will try to find the OID

View File

@ -0,0 +1,90 @@
package pgtype_test
import (
"context"
"fmt"
"os"
"time"
"github.com/jackc/pgx/v5"
)
// This example uses a single query to return parent and child records.
func Example_childRecords() {
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
}
// Setup example schema and data.
_, err = conn.Exec(ctx, `
create temporary table teams (
name text primary key
);
create temporary table players (
name text primary key,
team_name text,
position text
);
insert into teams (name) values
('Alpha'),
('Beta');
insert into players (name, team_name, position) values
('Adam', 'Alpha', 'wing'),
('Bill', 'Alpha', 'halfback'),
('Charlie', 'Alpha', 'fullback'),
('Don', 'Beta', 'halfback'),
('Edgar', 'Beta', 'halfback'),
('Frank', 'Beta', 'fullback')
`)
if err != nil {
fmt.Printf("Unable to setup example schema and data: %v", err)
return
}
type Player struct {
Name string
Position string
}
type Team struct {
Name string
Players []Player
}
rows, _ := conn.Query(ctx, `
select t.name,
(select array_agg(row(p.name, position) order by p.name) from players p where p.team_name = t.name)
from teams t
order by t.name
`)
teams, err := pgx.CollectRows(rows, pgx.RowToStructByPos[Team])
if err != nil {
fmt.Printf("CollectRows error: %v", err)
return
}
for _, team := range teams {
fmt.Println(team.Name)
for _, player := range team.Players {
fmt.Printf(" %s: %s\n", player.Name, player.Position)
}
}
// Output:
// Alpha
// Adam: wing
// Bill: halfback
// Charlie: fullback
// Beta
// Don: halfback
// Edgar: halfback
// Frank: fullback
}

View File

@ -39,7 +39,7 @@ func (src *Point) String() string {
return fmt.Sprintf("%.1f, %.1f", src.X, src.Y)
}
func Example_CustomType() {
func Example_customType() {
conn, err := pgx.Connect(context.Background(), os.Getenv("PGX_TEST_DATABASE"))
if err != nil {
fmt.Printf("Unable to establish connection: %v", err)

View File

@ -8,7 +8,7 @@ import (
"github.com/jackc/pgx/v5"
)
func Example_JSON() {
func Example_json() {
conn, err := pgx.Connect(context.Background(), os.Getenv("PGX_TEST_DATABASE"))
if err != nil {
fmt.Printf("Unable to establish connection: %v", err)