Documentation
¶
Overview ¶
Package sqlx maps database errors from database/sql and pgx into HTTP-friendly herodot errors.
Index ¶
- Variables
- func ClassifyPgError(err error) error
- func MapDBErrorHTTP(err error, resourceName string) *herodot.DefaultError
- func MapPgxErrorHTTP(err error, resourceName string) *herodot.DefaultError
- func NewMigratePgx(ctx context.Context, databaseURL string, migrationsFS fs.FS, ...) (*migrate.Migrate, func(), error)
- func NewMigrateSqlite(ctx context.Context, databaseURL string, migrationsFS fs.FS, dir string, ...) (*migrate.Migrate, func(), error)
Constants ¶
This section is empty.
Variables ¶
var ( // ErrAlreadyExists is wrapped by [ClassifyPgError] for unique constraint violations. ErrAlreadyExists = errors.New("already exists") // ErrConflict is wrapped by [ClassifyPgError] for foreign key violations. ErrConflict = errors.New("conflict") // ErrInvalid is wrapped by [ClassifyPgError] for not-null and check constraint violations. ErrInvalid = errors.New("invalid data") )
Functions ¶
func ClassifyPgError ¶
ClassifyPgError wraps a pgconn.PgError with one of ErrAlreadyExists, ErrConflict or ErrInvalid based on its SQLSTATE code, keeping the original error in the chain. Errors that are not a PgError, or have an unclassified code, are returned unchanged.
func MapDBErrorHTTP ¶
func MapDBErrorHTTP(err error, resourceName string) *herodot.DefaultError
MapDBErrorHTTP maps a database/sql error into a herodot error suitable for an HTTP response, translating sql.ErrNoRows into a not-found error and returning nil for a nil err. resourceName is used to build a human-readable reason (e.g. "user not found").
func MapPgxErrorHTTP ¶
func MapPgxErrorHTTP(err error, resourceName string) *herodot.DefaultError
MapPgxErrorHTTP maps a pgx error into a herodot error suitable for an HTTP response, returning nil for a nil err. It translates pgx.ErrNoRows into not-found, and constraint violations (see ClassifyPgError) into conflict or bad-request errors. resourceName is used to build a human-readable reason (e.g. "user not found").
func NewMigratePgx ¶
func NewMigratePgx(ctx context.Context, databaseURL string, migrationsFS fs.FS, logger *slog.Logger) (*migrate.Migrate, func(), error)
NewMigratePgx opens a PostgreSQL-backed *migrate.Migrate instance, connecting via a pgxpool.Pool built from databaseURL and reading migration files from the "migrations" directory of migrationsFS.
Callers own their migration files: embed them in the calling package, e.g.
//go:embed migrations/*.sql
var migrationsFS embed.FS
m, cleanup, err := sqlx.NewMigratePgx(ctx, dbURL, migrationsFS, logger)
if err != nil {
return err
}
defer cleanup()
On success the returned cleanup func closes the migrate instance and the underlying connection pool; it must be called exactly once, typically via defer, regardless of whether migrations are actually run. On error, all resources opened so far are closed internally and cleanup is nil.
func NewMigrateSqlite ¶
func NewMigrateSqlite(ctx context.Context, databaseURL string, migrationsFS fs.FS, dir string, logger *slog.Logger) (*migrate.Migrate, func(), error)
NewMigrateSqlite opens a SQLite-backed *migrate.Migrate instance, connecting via database/sql (using the pure-Go modernc.org/sqlite driver) to databaseURL and reading migration files from dir in migrationsFS.
Callers own their migration files: embed them in the calling package, e.g.
//go:embed migrations/*.sql
var migrationsFS embed.FS
m, cleanup, err := sqlx.NewMigrateSqlite(ctx, dbURL, migrationsFS, "migrations", logger)
if err != nil {
return err
}
defer cleanup()
On success the returned cleanup func closes the migrate instance, which in turn closes the underlying *sql.DB; it must be called exactly once, typically via defer, regardless of whether migrations are actually run. On error, all resources opened so far are closed internally and cleanup is nil.
Types ¶
This section is empty.