diff options
| author | Stefan Majewsky <majewsky@gmx.net> | 2026-05-12 23:32:28 +0200 |
|---|---|---|
| committer | Stefan Majewsky <majewsky@gmx.net> | 2026-05-12 23:32:28 +0200 |
| commit | a86a346ecceb7ad409f116474c1593b201012cf2 (patch) | |
| tree | 267505a9e6bba398f7a379a046df64a8aec45b1c /benchmark/internal/oblast_pgx/handle.go | |
| parent | 23fa77bbe1286b55e2526c0a965da1a4c3048415 (diff) | |
| download | go-oblast-a86a346ecceb7ad409f116474c1593b201012cf2.tar.gz | |
add PostgreSQL benchmark, comparing lib/pq against pgx both with and w/o Oblast
Diffstat (limited to 'benchmark/internal/oblast_pgx/handle.go')
| -rw-r--r-- | benchmark/internal/oblast_pgx/handle.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/benchmark/internal/oblast_pgx/handle.go b/benchmark/internal/oblast_pgx/handle.go new file mode 100644 index 0000000..6a88e2b --- /dev/null +++ b/benchmark/internal/oblast_pgx/handle.go @@ -0,0 +1,81 @@ +// SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net> +// SPDX-License-Identifier: Apache-2.0 + +package oblast_pgx + +import ( + "context" + "fmt" + "strconv" + "sync/atomic" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" + "go.xyrillian.de/oblast/handle" +) + +type Handle interface { + Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error) + Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error) + QueryRow(ctx context.Context, sql string, args ...any) pgx.Row +} + +var ( + _ Handle = &pgx.Conn{} + _ Handle = pgx.Tx(nil) +) + +// TODO: offer wrapping for pgxpool.Pool and pgxpool.Conn? +func Wrap(h Handle) handle.Handle { + switch h := h.(type) { + case *pgx.Conn: + return wrappedHandle{h} + case pgx.Tx: + return wrappedHandle{h} + default: + panic(fmt.Sprintf("unexpected type: %#v", h)) + } +} + +var preparedStatementId atomic.Uint64 + +type wrappedHandle struct { + inner Handle +} + +// Prepare implements the [handle.Handle] interface. +func (h wrappedHandle) Prepare(ctx context.Context, query string, repeated bool) (handle.Statement, error) { + if !repeated { + return wrappedUnpreparedStatement{query, h.inner}, nil + } + + name := "oblast_pgx_" + strconv.FormatUint(preparedStatementId.Add(1), 10) + switch inner := h.inner.(type) { + case *pgx.Conn: + stmt, err := inner.Prepare(ctx, name, query) + return wrappedPreparedStatement{ctx, stmt, h.inner}, err + case pgx.Tx: + stmt, err := inner.Conn().Prepare(ctx, name, query) + return wrappedPreparedStatement{ctx, stmt, h.inner}, err + default: + panic("unreachable") // because of the check in func Wrap() + } +} + +// Releases a prepared statement. +func deallocate(ctx context.Context, h Handle, stmt *pgconn.StatementDescription) error { + switch h := h.(type) { + case *pgx.Conn: + return h.Deallocate(ctx, stmt.Name) + case pgx.Tx: + return h.Conn().Deallocate(ctx, stmt.Name) + default: + panic("unreachable") // because of the check in func Wrap() + } +} + +// Query implements the [handle.Handle] interface. +func (h wrappedHandle) Query(ctx context.Context, query string, args []any) (handle.Rows, error) { + rows, err := h.inner.Query(ctx, query, args...) + return wrappedRows{rows}, err +} |
