Documentation
¶
Overview ¶
Package pgxguard integrates sqlguard with pgx/v5 — the native, dominant PostgreSQL driver for Go (pgx/pgxpool, not the database/sql shim).
It hooks pgx's own tracer seam (pgx.QueryTracer + pgx.BatchTracer), which is the idiomatic extension point every pgx ecosystem tool uses, so every Query/QueryRow/Exec and every SendBatch is analyzed without a method list or a wrapper type.
Composability is a first-class concern: pgx allows exactly one Tracer per config, and production services usually already set one (otelpgx). Apply and ApplyPool therefore *compose* with any existing tracer via pgx's own multitracer rather than overwriting it.
Usage with a pool:
cfg, _ := pgxpool.ParseConfig(dsn) pgxguard.ApplyPool(cfg) // composes with cfg.ConnConfig.Tracer if set pool, _ := pgxpool.NewWithConfig(ctx, cfg)
Usage with a single connection:
cfg, _ := pgx.ParseConfig(dsn) pgxguard.Apply(cfg) conn, _ := pgx.ConnectConfig(ctx, cfg)
Analysis is driven by the single sqlguard core (middleware.Guard), so redaction-by-default, stable fingerprints, the pluggable real-grammar parser, slow-query and N+1 detection all behave identically to the database/sql driver wrapper. Configure with the standard middleware options:
pgxguard.NewTracer(
middleware.WithSlowQueryThreshold(50*time.Millisecond),
middleware.WithN1Detection(10, time.Second),
)
Index ¶
- func Apply(cfg *pgx.ConnConfig, opts ...middleware.Option) *pgx.ConnConfig
- func ApplyPool(cfg *pgxpool.Config, opts ...middleware.Option) *pgxpool.Config
- type Tracer
- func (t *Tracer) ResetN1()
- func (t *Tracer) TraceBatchEnd(_ context.Context, _ *pgx.Conn, _ pgx.TraceBatchEndData)
- func (t *Tracer) TraceBatchQuery(_ context.Context, _ *pgx.Conn, data pgx.TraceBatchQueryData)
- func (t *Tracer) TraceBatchStart(ctx context.Context, _ *pgx.Conn, _ pgx.TraceBatchStartData) context.Context
- func (t *Tracer) TraceQueryEnd(ctx context.Context, _ *pgx.Conn, data pgx.TraceQueryEndData)
- func (t *Tracer) TraceQueryStart(ctx context.Context, _ *pgx.Conn, data pgx.TraceQueryStartData) context.Context
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
func Apply(cfg *pgx.ConnConfig, opts ...middleware.Option) *pgx.ConnConfig
Apply installs a sqlguard Tracer on a *pgx.ConnConfig, composing with any tracer already configured (via pgx's multitracer) instead of overwriting it — so it coexists with otelpgx and friends. opts are the standard middleware options. Returns the same cfg for chaining.
Types ¶
type Tracer ¶
type Tracer struct {
// contains filtered or unexported fields
}
Tracer implements pgx.QueryTracer and pgx.BatchTracer, driving every traced statement through the shared sqlguard analysis core.
It deliberately does not implement pgx.PrepareTracer: prepared statements are still analyzed when executed (execution routes through QueryTracer), so tracing Prepare as well would double-report findings and inflate N+1 counts. CopyFrom carries no SQL and is out of scope by nature.
func NewTracer ¶
func NewTracer(opts ...middleware.Option) *Tracer
NewTracer builds a Tracer. It accepts the standard sqlguard middleware options (WithAnalyzer, WithReporter, WithSlowQueryThreshold, WithParser, WithN1Detection, …) — the same option set the database/sql driver wrapper uses, so there is no parallel configuration surface to drift.
func (*Tracer) ResetN1 ¶
func (t *Tracer) ResetN1()
ResetN1 clears N+1 tracker state. Call it at a per-request boundary (e.g. end of an HTTP handler) to scope N+1 detection to one unit of work. No-op unless WithN1Detection was passed to NewTracer.
func (*Tracer) TraceBatchEnd ¶
TraceBatchEnd is a no-op (per-statement analysis happens in TraceBatchQuery).
func (*Tracer) TraceBatchQuery ¶
TraceBatchQuery analyzes each statement in a batch (static rules + N+1). Per-statement latency is not exposed by pgx's batch tracer — only the whole-batch round trip — so slow-query timing is intentionally not reported here rather than reported wrongly.
func (*Tracer) TraceBatchStart ¶
func (t *Tracer) TraceBatchStart(ctx context.Context, _ *pgx.Conn, _ pgx.TraceBatchStartData) context.Context
TraceBatchStart is a no-op: the batch's SQL is only known per-query, in TraceBatchQuery.
func (*Tracer) TraceQueryEnd ¶
TraceQueryEnd closes the latency window. Latency is recorded only on success (Guard.Observe drops it when data.Err != nil — a failed query's duration is meaningless).