diff --git a/pkg/database/db.go b/pkg/database/db.go index 925dc71..1efe16f 100644 --- a/pkg/database/db.go +++ b/pkg/database/db.go @@ -15,21 +15,30 @@ import ( "github.com/jackc/pgx/v4/pgxpool" ) +const ( + searchPathQuery = "set search_path to camper, public" +) + func ErrorIsNotFound(err error) bool { return errors.Is(err, pgx.ErrNoRows) } func New(ctx context.Context, connString string) (*DB, error) { + // Connect once with an “elevated” user to register types in camper schema + if err := registerTypes(ctx, connString); err != nil { + return nil, err + } + config, err := pgxpool.ParseConfig(connString) if err != nil { return nil, err } config.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error { - if _, err := conn.Exec(ctx, "set search_path to camper, public"); err != nil { + if _, err := conn.Exec(ctx, searchPathQuery); err != nil { return err } - return registerTypes(ctx, conn) + return registerConnectionTypes(ctx, conn) } config.AfterRelease = func(conn *pgx.Conn) bool { @@ -44,6 +53,7 @@ func New(ctx context.Context, connString string) (*DB, error) { if err != nil { return nil, err } + return &DB{pool}, nil } diff --git a/pkg/database/types.go b/pkg/database/types.go index baaf6cc..eee9ca1 100644 --- a/pkg/database/types.go +++ b/pkg/database/types.go @@ -21,7 +21,26 @@ var ( oidCache = make(map[string]uint32) ) -func registerTypes(ctx context.Context, conn *pgx.Conn) error { +func registerTypes(ctx context.Context, connString string) error { + conn, err := pgx.Connect(ctx, connString) + if err != nil { + return err + } + defer conn.Close(context.Background()) + + if _, err := conn.Exec(ctx, "set role to guest"); err != nil { + return err + } + if _, err := conn.Exec(ctx, searchPathQuery); err != nil { + return err + } + if err := registerConnectionTypes(ctx, conn); err != nil { + return err + } + return nil +} + +func registerConnectionTypes(ctx context.Context, conn *pgx.Conn) error { uriOID, err := registerType(ctx, conn, &pgtype.Text{}, "uri") if err != nil { return err