From efeea0aef5c3e9e87bb19983c17c357fdb26063d Mon Sep 17 00:00:00 2001 From: Konstantin Grachev Date: Mon, 26 Jan 2026 20:33:04 +0300 Subject: [PATCH] feat: export PoolBatchResults, ErrBatchResults, ErrRows and ErrRow --- batch.go | 24 ++++++++++++++++++++++++ pgxpool/batch_results.go | 24 ++++-------------------- pgxpool/pool.go | 10 +++++----- pgxpool/rows.go | 20 -------------------- rows.go | 28 ++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 45 deletions(-) diff --git a/batch.go b/batch.go index 2307e3cc8..3f99237cf 100644 --- a/batch.go +++ b/batch.go @@ -505,3 +505,27 @@ func invalidateCachesOnBatchResultsError(conn *Conn, b *Batch, err error) { } } } + +type errBatchResults struct { + err error +} + +func ErrBatchResults(err error) BatchResults { + return errBatchResults{err: err} +} + +func (br errBatchResults) Exec() (pgconn.CommandTag, error) { + return pgconn.CommandTag{}, br.err +} + +func (br errBatchResults) Query() (Rows, error) { + return ErrRows(br.err), br.err +} + +func (br errBatchResults) QueryRow() Row { + return ErrRow(br.err) +} + +func (br errBatchResults) Close() error { + return br.err +} diff --git a/pgxpool/batch_results.go b/pgxpool/batch_results.go index 5d5c681d5..e9f9ae45e 100644 --- a/pgxpool/batch_results.go +++ b/pgxpool/batch_results.go @@ -5,31 +5,15 @@ import ( "github.com/jackc/pgx/v5/pgconn" ) -type errBatchResults struct { - err error -} - -func (br errBatchResults) Exec() (pgconn.CommandTag, error) { - return pgconn.CommandTag{}, br.err -} - -func (br errBatchResults) Query() (pgx.Rows, error) { - return errRows{err: br.err}, br.err -} - -func (br errBatchResults) QueryRow() pgx.Row { - return errRow{err: br.err} -} - -func (br errBatchResults) Close() error { - return br.err -} - type poolBatchResults struct { br pgx.BatchResults c *Conn } +func PoolBatchResults(br pgx.BatchResults, c *Conn) pgx.BatchResults { + return &poolBatchResults{br: br, c: c} +} + func (br *poolBatchResults) Exec() (pgconn.CommandTag, error) { return br.br.Exec() } diff --git a/pgxpool/pool.go b/pgxpool/pool.go index 4c3e8526f..5c810c73a 100644 --- a/pgxpool/pool.go +++ b/pgxpool/pool.go @@ -737,13 +737,13 @@ func (p *Pool) Exec(ctx context.Context, sql string, arguments ...any) (pgconn.C func (p *Pool) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error) { c, err := p.Acquire(ctx) if err != nil { - return errRows{err: err}, err + return pgx.ErrRows(err), err } rows, err := c.Query(ctx, sql, args...) if err != nil { c.Release() - return errRows{err: err}, err + return pgx.ErrRows(err), err } return c.getPoolRows(rows), nil @@ -764,7 +764,7 @@ func (p *Pool) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, er func (p *Pool) QueryRow(ctx context.Context, sql string, args ...any) pgx.Row { c, err := p.Acquire(ctx) if err != nil { - return errRow{err: err} + return pgx.ErrRow(err) } row := c.QueryRow(ctx, sql, args...) @@ -774,11 +774,11 @@ func (p *Pool) QueryRow(ctx context.Context, sql string, args ...any) pgx.Row { func (p *Pool) SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults { c, err := p.Acquire(ctx) if err != nil { - return errBatchResults{err: err} + return pgx.ErrBatchResults(err) } br := c.SendBatch(ctx, b) - return &poolBatchResults{br: br, c: c} + return PoolBatchResults(br, c) } // Begin acquires a connection from the Pool and starts a transaction. Unlike database/sql, the context only affects the begin command. i.e. there is no diff --git a/pgxpool/rows.go b/pgxpool/rows.go index f834b7ec3..eb6201532 100644 --- a/pgxpool/rows.go +++ b/pgxpool/rows.go @@ -5,26 +5,6 @@ import ( "github.com/jackc/pgx/v5/pgconn" ) -type errRows struct { - err error -} - -func (errRows) Close() {} -func (e errRows) Err() error { return e.err } -func (errRows) CommandTag() pgconn.CommandTag { return pgconn.CommandTag{} } -func (errRows) FieldDescriptions() []pgconn.FieldDescription { return nil } -func (errRows) Next() bool { return false } -func (e errRows) Scan(dest ...any) error { return e.err } -func (e errRows) Values() ([]any, error) { return nil, e.err } -func (e errRows) RawValues() [][]byte { return nil } -func (e errRows) Conn() *pgx.Conn { return nil } - -type errRow struct { - err error -} - -func (e errRow) Scan(dest ...any) error { return e.err } - type poolRows struct { r pgx.Rows c *Conn diff --git a/rows.go b/rows.go index dbf0a6c96..aa1a076a2 100644 --- a/rows.go +++ b/rows.go @@ -70,6 +70,24 @@ type Rows interface { Conn() *Conn } +type errRows struct { + err error +} + +func ErrRows(err error) Rows { + return errRows{err: err} +} + +func (errRows) Close() {} +func (e errRows) Err() error { return e.err } +func (errRows) CommandTag() pgconn.CommandTag { return pgconn.CommandTag{} } +func (errRows) FieldDescriptions() []pgconn.FieldDescription { return nil } +func (errRows) Next() bool { return false } +func (e errRows) Scan(dest ...any) error { return e.err } +func (e errRows) Values() ([]any, error) { return nil, e.err } +func (e errRows) RawValues() [][]byte { return nil } +func (e errRows) Conn() *Conn { return nil } + // Row is a convenience wrapper over Rows that is returned by QueryRow. // // Row is an interface instead of a struct to allow tests to mock QueryRow. However, @@ -83,6 +101,16 @@ type Row interface { Scan(dest ...any) error } +type errRow struct { + err error +} + +func ErrRow(err error) Row { + return errRow{err: err} +} + +func (e errRow) Scan(dest ...any) error { return e.err } + // RowScanner scans an entire row at a time into the RowScanner. type RowScanner interface { // ScanRows scans the row.