Documentation
¶
Overview ¶
Package pgxprepared demonstrates a bounded cache of SQLGuard prepared values in front of pgx-style Exec, Query, and QueryRow operations. Cache hits reuse parsing but every call repeats prepared validation before the wrapped executor is invoked.
The cache retains exact SQL strings as keys. Its SQLGuard Prepared values retain parsed identifiers, literals, and byte values. Applications should prefer stable parameterized SQL with positional arguments instead of embedding sensitive values. Cache capacity and MaxSQLBytes bound entry count and eligible key length; they are retention controls, not a heap quota, because parsed-tree size is not measured. Eviction and Go garbage collection do not guarantee prompt memory zeroization.
SQLGuard Prepared values are client-side parsed representations, not pgx or PostgreSQL server prepared statements. Executing a manually registered statement by passing its name as SQL is unsupported because pgx may execute text different from the string validated by this wrapper. Batch operations, transactions (including nested transactions), CopyFrom, and calls through an unwrapped executor are also outside the guarded boundary. Arguments that implement pgx.QueryRewriter are rejected.
This package is an illustrative example, not an official production adapter. Its API has no compatibility guarantee.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrQueryRewriterUnsupported = errors.New(
"sqlguard pgx-prepared 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 CacheOptions ¶
CacheOptions configures bounded prepared-value retention for one GuardedDB.
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 prepared-validation cache around a narrow subset of pgx. It is an illustrative example rather than a production-ready adapter.
Example ¶
package main
import (
"context"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
sqlguard "github.com/almostinf/postgres-sqlguard"
pgxprepared "github.com/almostinf/postgres-sqlguard/example/pgx-prepared"
)
type exampleExecutor struct{}
func (exampleExecutor) Exec(context.Context, string, ...any) (pgconn.CommandTag, error) {
return pgconn.NewCommandTag("UPDATE 1"), nil
}
func (exampleExecutor) Query(context.Context, string, ...any) (pgx.Rows, error) {
return nil, nil
}
func (exampleExecutor) QueryRow(context.Context, string, ...any) pgx.Row {
return nil
}
func main() {
engine, err := sqlguard.NewEngine(sqlguard.EngineOptions{})
if err != nil {
return
}
guarded, err := pgxprepared.NewGuardedDB(engine, exampleExecutor{}, pgxprepared.CacheOptions{
Capacity: 128,
MaxSQLBytes: 4096,
})
if err != nil {
return
}
const sql = "UPDATE accounts SET active = $1 WHERE id = $2"
_, _ = guarded.Exec(context.Background(), sql, true, 42)
_, _ = guarded.Exec(context.Background(), sql, false, 84)
}
Output:
func NewGuardedDB ¶
func NewGuardedDB( validator PreparedValidator, executor Executor, options CacheOptions, ) (*GuardedDB, error)
NewGuardedDB validates its collaborators and cache limits and constructs an illustrative pgx wrapper with a private fixed-capacity LRU cache.
func (*GuardedDB) Exec ¶
func (db *GuardedDB) Exec( ctx context.Context, sql string, arguments ...any, ) (pgconn.CommandTag, error)
Exec validates SQL through the prepared cache before delegating to the wrapped executor.