Register PostgreSQL types once on start with guest user

There are types inaccessible to the authenticator role, such as
redsys_request, that can not be registered because that roles is unable
to get the OID of.

I could have moved these types to the public schema, but then it would
seem pointless to have a separate schema.
This commit is contained in:
jordi fita mas 2023-12-13 16:47:31 +01:00
parent cfd5d5675c
commit 6c090a63da
2 changed files with 32 additions and 3 deletions

View File

@ -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
}

View File

@ -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