Documentation
¶
Overview ¶
Package pgxexample demonstrates how to place a sqlguard validator in front of a narrow pgx execution boundary.
This package is an illustrative example, not an official production adapter. Its API has no compatibility guarantee. GuardedDB protects only Exec, Query, and QueryRow calls that use positional arguments. QueryRow reports validation failures through Scan, following pgx's deferred-error convention.
Batch execution, prepared statement workflows, transactions (including nested transactions), CopyFrom, and calls made through a retained raw pgx connection or pool are outside this example's validation boundary. Arguments implementing pgx.QueryRewriter are rejected before validation or delegation; consequently pgx NamedArgs, StrictNamedArgs, StructArgs, and StrictStructArgs are unsupported.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrQueryRewriterUnsupported = errors.New("sqlguard pgx example: query rewriting is unsupported")
ErrQueryRewriterUnsupported reports that an argument could replace SQL after it has passed validation.
Functions ¶
This section is empty.
Types ¶
type Executor ¶
type Executor interface {
Exec(ctx context.Context, sql string, arguments ...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
}
Executor is the subset of pgx connection and pool operations guarded by the example.
type GuardedDB ¶
type GuardedDB struct {
// contains filtered or unexported fields
}
GuardedDB demonstrates a validation boundary around a narrow subset of pgx. It is an illustrative example rather than a production-ready adapter.
func NewGuardedDB ¶
NewGuardedDB constructs an illustrative pgx wrapper from non-nil collaborators.
Example ¶
package main
import (
"context"
"github.com/jackc/pgx/v5/pgxpool"
sqlguard "github.com/almostinf/postgres-sqlguard"
pgxexample "github.com/almostinf/postgres-sqlguard/example/pgx"
"github.com/almostinf/postgres-sqlguard/pkg/rules"
)
func main() {
ctx := context.Background()
pool, err := pgxpool.New(ctx, "postgres://postgres@localhost/application")
if err != nil {
return
}
defer pool.Close()
engine, err := sqlguard.NewEngine(
sqlguard.EngineOptions{},
rules.NewUpdateRequiresWhere(),
rules.NewDeleteRequiresWhere(),
)
if err != nil {
return
}
database, err := pgxexample.NewGuardedDB(engine, pool)
if err != nil {
return
}
_, err = database.Exec(
ctx,
"UPDATE accounts SET active = $1 WHERE id = $2",
false,
42,
)
if err != nil {
return
}
}
Output:
func (*GuardedDB) Exec ¶
func (db *GuardedDB) Exec( ctx context.Context, sql string, arguments ...any, ) (pgconn.CommandTag, error)
Exec validates SQL before delegating to the wrapped executor.