pgxx

package module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2025 License: MIT Imports: 12 Imported by: 0

README

pgxx

Go Reference

A high-level helper for pgx where most operations are done with a single function call that takes and returns standard go and pgx types. Functionality is heavily inspired by sqlx, but uses the raw pgx interface instead of database/sql for increased efficiency and to support ACID transactions in both batched and retry-loop modes (neither of which arre supported by database/sql).

For example usage, see integration_test.go.

When scanning results and resolving named parameters, columns are mapped to struct fields tagged with db:"column_name" (fields without this tag are ignored). Additionally, to support composite fields and ad-hoc joins, a struct field can instead be tagged with db_prefix, to embed its tagged fields into the parent's mapping with a custom prefix.

In order to keep the API simple, functions based on reflection will panic on type errors (if the any parameter is not a struct or pointer-to-struct, or if it is missing the requested named parameters) unless otherwise indicated.

Documentation

Overview

Pgxx is high-level client providing cursor-struct mapping for Postgres using pgx.

Basic functionality is provided by Exec, Query, QueryOne, and QueryExactlyOne (which use queries with positional parameters) and their Named counterparts (which use named parameters extracted from a struct).

In order to prevent accidental injection, all queries use the SQL type (compatible with standard string literals). In order to more easily list fields in queries, this package contains a number of helper functions to format lists of fields in various contexts (such as ListFields) as well as the DBFields function to get the lase of mapable fields for a given go type.

For ACID transactions use RunInTx, which provides collision detection and a client-side retry loop. If all queries areindependent of each other, the entire transaction may be run in a single round-trip using the batch API, accessed through NewBatch, RunBatch and the various Queue functions (such as QueueQuery).

Index

Constants

This section is empty.

Variables

View Source
var DefaultTxOptions = pgx.TxOptions{
	IsoLevel: pgx.Serializable,
}

SERIALIZABLE transaction options for use with client-side retry.

View Source
var MaxTxRetries int = 10

Maximum number of times to retry a transaction on collision before erroring out. Changeable.

Functions

func Exec

func Exec(ctx context.Context, conn PoolOrTx, query SQL, args ...any) (int, error)

Run a statement with positional parameters and return the number of rows affected.

func ExecExactlyOne

func ExecExactlyOne(ctx context.Context, conn PoolOrTx, query SQL, args ...any) error

Run a statement with positional parameters effecting exactly one row. Errors if no or nultiple rows are affected.

func ExtractCopyParams

func ExtractCopyParams[T any](fields []FieldName, records []T) [][]any

Extracts fields from a slice of structs for a CopyFrom (bulk insert) query

func Head[T any](xs []T) *T

Helper function to return the first item of a list, or nil if empty

func IsTxCollisionError

func IsTxCollisionError(err error) bool

Returns if a (possibly wrapped) error is due to a transaction being clobbered by other dbactivity. If this returns true, the transaction should be retried.

func IsUniqueViolationError

func IsUniqueViolationError(err error) bool

Transactions inserting with random keys generated within the transaction might want to retry on a unique constraint failure.

func NamedCopyFrom

func NamedCopyFrom[T any](ctx context.Context, conn PoolOrTx, tableName SQL, fields []FieldName, records []T) (int, error)

Runs a COPY FROM STDIN query for bulk insertion, with the records to insert passed in as structs.

func NamedExec

func NamedExec(ctx context.Context, conn PoolOrTx, namedQuery SQL, argsStruct any) (int, error)

Run a statement with named parameters (pulling them out of a struct) and return the number of rows affected.

func NamedExecExactlyOne

func NamedExecExactlyOne(ctx context.Context, conn PoolOrTx, namedQuery SQL, argsStruct any) error

Run a statement with named parameters (pulling them out of a struct) effecting exactly one row. Errors if no or nultiple rows are affected.

func NamedQuery

func NamedQuery[T any](ctx context.Context, conn PoolOrTx, namedQuery SQL, argsStruct any) ([]T, error)

Run a query with named parameters parameters (pulling them out of a struct) and read out the results as a slice of either structs (for multiple-column queries) or primitives (for single-column queries only).

func NamedQueryExactlyOne

func NamedQueryExactlyOne[T any](ctx context.Context, conn PoolOrTx, namedQuery SQL, argsStruct any) (T, error)

Run a query with named parameters parameters (pulling them out of a struct) that returns at most one row and read out the results as a struct (for multiple-column queries) or a primitive (for single-column queries only). Errors if zero or multiple rows are produced.

func NamedQueryOne

func NamedQueryOne[T any](ctx context.Context, conn PoolOrTx, namedQuery SQL, argsStruct any) (T, error)

Run a query with named parameters parameters (pulling them out of a struct) that returns at most one row and read out the results as a struct (for multiple-column queries) or a primitive (for single-column queries only). Returns the zero value if the query produces no rows. Discards if multiple rows are produced.

func NewBatch

func NewBatch() *pgx.Batch

Allocates a new Batch

func NotNil

func NotNil[T any](x T) *T

Function to generate a pointer to a constant calue inside an expression. Useful for nullable fields in struct literals.

func OrZero

func OrZero[T any](p *T) T

Safe dereferencing of a pointer with fallback.

func Query

func Query[T any](ctx context.Context, conn PoolOrTx, query SQL, args ...any) ([]T, error)

Run a query with positional parameters and read out the results as a slice of either structs (for multiple-column queries) or primitives (for single-column queries only).

func QueryExactlyOne

func QueryExactlyOne[T any](ctx context.Context, conn PoolOrTx, query SQL, args ...any) (T, error)

Run a query with positional parameters that returns at most one row and read out the results as a struct (for multiple-column queries) or a primitive (for single-column queries only). Errors if zero or multiple rows are produced.

func QueryOne

func QueryOne[T any](ctx context.Context, conn PoolOrTx, query SQL, args ...any) (T, error)

Run a query with positional parameters that returns at most one row and read out the results as a struct (for multiple-column queries) or a primitive (for single-column queries only). Returns the zero value if the query produces no rows. Discards if multiple rows are produced.

func QueueExec

func QueueExec(batch *pgx.Batch, out *int, query SQL, args ...any)

Version of Exec which queues to a batch. If out is not nil, writes the number of rows affected there when the batch is run.

func QueueNamedExec

func QueueNamedExec(batch *pgx.Batch, out *int, namedQuery SQL, argsStruct any)

Version of NamedExec which queues to a batch. If out is not nil, writes the number of rows affected there when the batch is run.

func QueueNamedQuery

func QueueNamedQuery[T any](batch *pgx.Batch, out *[]T, namedQuery SQL, argsStruct any)

Version of Query which queues to a batch. Writes results into *out (which must not be nil) when the batch is run.

func QueueNamedQueryOne

func QueueNamedQueryOne[T any](batch *pgx.Batch, out *T, namedQuery SQL, argsStruct any)

Version of NamedQueryOne which queues to a batch. Writes results into *out (which must not be nil) when the batch is run.

func QueueQuery

func QueueQuery[T any](batch *pgx.Batch, out *[]T, query SQL, args ...any)

Version of Query which queues to a batch. Writes results into *out (which must not be nil) when the batch is run.

func QueueQueryOne

func QueueQueryOne[T any](batch *pgx.Batch, out *T, query SQL, args ...any)

Version of QueryOne which queues to a batch. Writes result into *out (which must not be nil) when the batch is run.

func RewriteNamedQuery

func RewriteNamedQuery(namedQuery SQL) (SQL, []FieldName)

func RunBatch

func RunBatch(ctx context.Context, conn PoolOrTx, batch *pgx.Batch) error

Runs a batch of state,emts in a single operation, which can significantly reduce the number of network roundtrips required. Can take a pool or connection to use an implicit transaction (BEGIN and COMMIT may be added to the batch to add options, but are not necessary).

func RunInTx

func RunInTx(ctx context.Context, conn TxContext, retryableAction func(pgx.Tx) error) error

Runs a action inside a SERIALIZABLE transaction with client-side retry.

func RunInTxWithOptions

func RunInTxWithOptions(ctx context.Context, conn TxContext, txOptions pgx.TxOptions, retryOnUniqueViolation bool, retryableAction func(pgx.Tx) error) error

Runs a transaction in a client-side retry loop to handle collisions. Safe to use in serializable/ACID mode. retryableAction must be idempotent in its non-db side-effects as it will be run multiple times if the transaction retries.

func ScanRows

func ScanRows[T any](rows pgx.Rows, dst *[]T) error

Scan rows to a slice of either structs (using the mapping defined by db and db_prefix tags) or single values (for queries returning a single column).

func ScanSingleRow

func ScanSingleRow[T any](rows pgx.Rows, dst *T, requireExact bool) error

Scan a single row from a query result. If requireExact is true, errors on an empty result set or too many rows, if it is false, discard extra rows and leave dst unchanged if empty.

Types

type FieldName

type FieldName string

func DBFields

func DBFields[T any]() []FieldName

Returns the tags of all struct fields tagged with `db`, including those inside embedded structs. Does not deduplicate.

type PoolOrTx

type PoolOrTx interface {
	Exec(ctx context.Context, sql string, arguments ...any) (commandTag pgconn.CommandTag, err error)
	Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)
	SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults
	CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error)
}

Context in which to do database operations. Can be a Pool, Conn, or Tx

type SQL

type SQL string

String type for SQL literals. Having this be a separate type instead of string helps prevent accidental SQL injection.

func ExtractNamedQuery

func ExtractNamedQuery(query SQL, argsStruct any) (SQL, []any)

Bidirectional mapping between structs, cursors, and queries.

Converts a query with named parameters (using the @param syntak of pgx.NamedArgs) to one using positional parameters. Panics if a query does not match the type of struct given, to simplify use with hardcoded queries.

func ListFields

func ListFields(fields []FieldName) SQL

Produces a list of fields comma-separated for use in queries

func ListFieldsWithPrefix

func ListFieldsWithPrefix(fields []FieldName, queryPrefix SQL, resultPrefix SQL) SQL

Used to prefix a list of fields, using sepatate prefixes on wither side of the AS. When used with the db_prefix tag of the result set, this is quite useful for joins with conflicting field names when used in the form `ListFieldsWithPrefix(AllAFields, "a.", "a_")`.

func ListNamedFieldParams

func ListNamedFieldParams(fields []FieldName) SQL

Produces a list of fields as named parameters

func MaybeExtractNamedQuery

func MaybeExtractNamedQuery(query SQL, argsStruct any) (SQL, []any, error)

Error-tolerant version of ExtractNamedQuery for use with dynamic query strings

func NamedInsertQuery

func NamedInsertQuery(tableName SQL, fields []FieldName) SQL

Produces an INSERT query from a list of fields which uses named parameters matching the field names

type Tx

type Tx = pgx.Tx

re-export for convienence

type TxContext

type TxContext interface {
	BeginTx(ctx context.Context, txOptions pgx.TxOptions) (pgx.Tx, error)
}

A pool or single connection.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL