mysql

package
v0.12.14-0...-e6bae5f Latest Latest
Warning

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

Go to latest
Published: May 15, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package mysql provides a minimal shared MySQL abstraction for backend services.

The package intentionally stays small: it owns connection setup, read/write replica selection, tracing/metrics wrappers, transaction helpers, and MySQL-specific error classification. Query logic stays in caller packages. This keeps Bazel cache keys stable for dependents and avoids pulling service-specific SQL concerns into a base dependency.

New requires [Config.PrimaryDSN] and enforces `parseTime=true` in DSNs so datetime values decode correctly. When [Config.ReadOnlyDSN] is empty, reads and writes use the same underlying pool. Use [Database.RW] for writes and [Database.RO] for read paths.

Generated query code should depend on DBTX, so the same query methods can run against either a Replica or a transaction. Use Tx / TxWithResult for single-attempt transactions, and TxRetry / TxWithResultRetry when the operation is safe to retry on transient failures.

Retry helpers only retry errors classified as transient by IsTransientError. IsNotFound and IsDuplicateKeyError are treated as terminal and are not retried.

Index

Constants

View Source
const (
	// DefaultBackoff is the base duration for exponential backoff in database retries
	DefaultBackoff = 50 * time.Millisecond
	// DefaultAttempts is the maximum number of retry attempts for database operations
	DefaultAttempts = 3
)

Variables

This section is empty.

Functions

func IsConnectionError

func IsConnectionError(err error) bool

IsConnectionError returns true if the error indicates a connection problem.

func IsDeadlockError

func IsDeadlockError(err error) bool

IsDeadlockError returns true if the error is a MySQL deadlock error (1213).

func IsDuplicateKeyError

func IsDuplicateKeyError(err error) bool

IsDuplicateKeyError reports whether err is MySQL error 1062 (duplicate key / unique constraint violation).

func IsLockWaitTimeoutError

func IsLockWaitTimeoutError(err error) bool

IsLockWaitTimeoutError returns true if the error is a MySQL lock wait timeout error (1205).

func IsNotFound

func IsNotFound(err error) bool

IsNotFound returns true if the error is sql.ErrNoRows. Use this for consistent not-found handling across the codebase.

func IsTooManyConnectionsError

func IsTooManyConnectionsError(err error) bool

IsTooManyConnectionsError returns true if the error is a MySQL too many connections error (1040).

func IsTransientError

func IsTransientError(err error) bool

IsTransientError returns true if the error is a transient MySQL error that should be retried.

func New

func New(config Config) (*database, error)

New creates a new database instance with the provided configuration. It establishes connections to the primary database and optionally to a read-only replica. Returns an error if connections cannot be established or if DSNs are misconfigured.

func NewFromReplicas

func NewFromReplicas(ro, rw *Replica) *database

NewFromReplicas creates a MySQL from pre-existing replicas without opening new connections. This is a temporary bridge used by pkg/db.ToMySQL while callers migrate from pkg/db to pkg/mysql. Remove alongside NewReplicaFromDB and pkg/db.ToMySQL once all callers use New directly.

func Tx

func Tx(ctx context.Context, db *Replica, fn func(context.Context, DBTX) error) error

Tx executes fn within a database transaction without returning a result. It is a convenience wrapper around TxWithResult for operations that only need error handling.

func TxRetry

func TxRetry(ctx context.Context, db *Replica, fn func(context.Context, DBTX) error) error

TxRetry executes a transaction with automatic retry on transient errors like deadlocks. It is a convenience wrapper around TxWithResultRetry for operations that don't return a value.

func TxWithResult

func TxWithResult[T any](ctx context.Context, db *Replica, fn func(context.Context, DBTX) (T, error)) (T, error)

TxWithResult executes fn within a database transaction and returns the result. It begins a transaction on db, executes fn with the transaction context, and commits on success or rolls back on failure.

func TxWithResultRetry

func TxWithResultRetry[T any](ctx context.Context, db *Replica, fn func(context.Context, DBTX) (T, error)) (T, error)

TxWithResultRetry executes a transaction with automatic retry on transient errors.

func WithRetryContext

func WithRetryContext[T any](ctx context.Context, fn func() (T, error)) (T, error)

WithRetryContext executes a database operation with optimized retry configuration while respecting context cancellation and deadlines.

Types

type Config

type Config struct {
	// The primary DSN for your database. This must support both reads and writes.
	PrimaryDSN string

	// The readonly replica will be used for most read queries.
	// If omitted, the primary is used.
	ReadOnlyDSN string
}

Config defines the parameters needed to establish database connections. It supports separate connections for read and write operations to allow for primary/replica setups.

type DBTX

type DBTX interface {
	ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
	PrepareContext(context.Context, string) (*sql.Stmt, error)
	QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
	QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}

DBTX is an interface that abstracts database operations for both direct connections and transactions. It allows query methods to work with either a database or transaction, making transaction handling more flexible.

This interface is implemented by both sql.DB and sql.Tx, as well as the custom Replica type in this package.

type DBTx

type DBTx interface {
	DBTX
	Commit() error
	Rollback() error
}

DBTx represents a database transaction with commit and rollback capabilities. It extends DBTX with transaction-specific methods.

func WrapTxWithContext

func WrapTxWithContext(tx *sql.Tx, mode string, ctx context.Context) DBTx

WrapTxWithContext wraps a standard sql.Tx with our DBTx interface for tracing, using the provided context

type Database

type Database = MySQL

backwards compatible type until we move all services to use the MySQL interface directly

type MySQL

type MySQL interface {
	// RW returns the write (primary) replica for write operations
	RW() *Replica

	// RO returns the read replica for read operations
	// If no read replica is configured, it returns the write replica
	RO() *Replica

	// Close properly terminates all database connections
	Close() error
}

MySQL defines the interface for database operations, providing access to read and write replicas and the ability to close connections.

type Replica

type Replica struct {
	// contains filtered or unexported fields
}

Replica wraps a standard SQL database connection and implements the DBTX interface to enable interaction with the generated database code.

func NewReplica

func NewReplica(url string, mode string) (*Replica, error)

func NewReplicaFromDB

func NewReplicaFromDB(db *sql.DB, mode string) *Replica

NewReplicaFromDB wraps an existing *sql.DB as a *Replica with tracing and metrics. This is a temporary bridge used by pkg/db.ToMySQL while callers migrate from pkg/db to pkg/mysql. Remove alongside NewFromReplicas and pkg/db.ToMySQL once all callers use New directly.

func (*Replica) Begin

func (r *Replica) Begin(ctx context.Context) (DBTx, error)

Begin starts a transaction and returns it. This method provides a way to use the Replica in transaction-based operations.

func (*Replica) Close

func (r *Replica) Close() error

func (*Replica) ExecContext

func (r *Replica) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)

ExecContext executes a SQL statement and returns a result summary. It's used for INSERT, UPDATE, DELETE statements that don't return rows.

func (*Replica) PrepareContext

func (r *Replica) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)

PrepareContext prepares a SQL statement for later execution.

func (*Replica) QueryContext

func (r *Replica) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)

QueryContext executes a SQL query that returns rows.

func (*Replica) QueryRowContext

func (r *Replica) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row

QueryRowContext executes a SQL query that returns a single row.

type TracedTx

type TracedTx struct {
	// contains filtered or unexported fields
}

TracedTx wraps a sql.Tx to add tracing to all database operations within a transaction

func (*TracedTx) Commit

func (t *TracedTx) Commit() error

Commit commits the transaction with tracing

func (*TracedTx) ExecContext

func (t *TracedTx) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)

ExecContext executes a SQL statement within the transaction with tracing

func (*TracedTx) PrepareContext

func (t *TracedTx) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)

PrepareContext prepares a SQL statement within the transaction with tracing

func (*TracedTx) QueryContext

func (t *TracedTx) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)

QueryContext executes a SQL query within the transaction with tracing

func (*TracedTx) QueryRowContext

func (t *TracedTx) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row

QueryRowContext executes a SQL query that returns a single row within the transaction with tracing

func (*TracedTx) Rollback

func (t *TracedTx) Rollback() error

Rollback rolls back the transaction with tracing

Directories

Path Synopsis
Package metrics defines Prometheus metrics used by pkg/mysql wrappers.
Package metrics defines Prometheus metrics used by pkg/mysql wrappers.

Jump to

Keyboard shortcuts

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