package dbutil
import "go.mau.fi/util/dbutil"
Index ¶
- Constants
- Variables
- func NumPtr[T constraints.Integer | constraints.Float](val T) *T
- func ScanDataStruct[T NewableDataStruct[T]](rows Scannable) (T, error)
- func ScanSingleColumn[T any](rows Scannable) (val T, err error)
- func StrPtr[T ~string](val T) *string
- func ValueOrErr[T any](val *T, err error) (*T, error)
- type Config
- type DataStruct
- type Database
- func NewFromConfig(owner string, cfg Config, logger DatabaseLogger) (*Database, error)
- func NewWithDB(db *sql.DB, rawDialect string) (*Database, error)
- func NewWithDialect(uri, rawDialect string) (*Database, error)
- func (db *Database) BeginTx(ctx context.Context, opts *sql.TxOptions) (*LoggingTxn, error)
- func (db *Database) Child(versionTable string, upgradeTable UpgradeTable, log DatabaseLogger) *Database
- func (db *Database) Close() error
- func (db *Database) ColumnExists(ctx context.Context, table, column string) (exists bool, err error)
- func (db *Database) Configure(cfg Config) error
- func (db *Database) Conn(ctx context.Context) Execable
- func (db *Database) DoTxn(ctx context.Context, opts *sql.TxOptions, fn func(ctx context.Context) error) error
- func (db *Database) Exec(ctx context.Context, query string, args ...any) (sql.Result, error)
- func (db *Database) Query(ctx context.Context, query string, args ...any) (Rows, error)
- func (db *Database) QueryRow(ctx context.Context, query string, args ...any) *sql.Row
- func (db *Database) TableExists(ctx context.Context, table string) (exists bool, err error)
- func (db *Database) Upgrade(ctx context.Context) error
- type DatabaseLogger
- func ZeroLogger(log zerolog.Logger, cfg ...ZeroLogSettings) DatabaseLogger
- func ZeroLoggerPtr(log *zerolog.Logger, cfg ...ZeroLogSettings) DatabaseLogger
- type Dialect
- type Execable
- type JSON
- type LoggingExecable
- func (le *LoggingExecable) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
- func (le *LoggingExecable) QueryContext(ctx context.Context, query string, args ...any) (Rows, error)
- func (le *LoggingExecable) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
- type LoggingRows
- func (lrs *LoggingRows) Close() error
- func (lrs *LoggingRows) ColumnTypes() ([]*sql.ColumnType, error)
- func (lrs *LoggingRows) Columns() ([]string, error)
- func (lrs *LoggingRows) Err() error
- func (lrs *LoggingRows) Next() bool
- func (lrs *LoggingRows) NextResultSet() bool
- func (lrs *LoggingRows) Scan(dest ...any) error
- type LoggingTxn
- type NewableDataStruct
- type PQErrorWithLine
- type PoolConfig
- type QueryHelper
- func MakeQueryHelper[T DataStruct[T]](db *Database, new func(qh *QueryHelper[T]) T) *QueryHelper[T]
- func (qh *QueryHelper[T]) Exec(ctx context.Context, query string, args ...any) error
- func (qh *QueryHelper[T]) GetDB() *Database
- func (qh *QueryHelper[T]) New() T
- func (qh *QueryHelper[T]) QueryMany(ctx context.Context, query string, args ...any) ([]T, error)
- func (qh *QueryHelper[T]) QueryOne(ctx context.Context, query string, args ...any) (val T, err error)
- type RowIter
- type Rows
- type Scannable
- type Transaction
- type UnderlyingExecable
- type UpgradeTable
- func (ut *UpgradeTable) Register(from, to, compat int, message string, txn bool, fn upgradeFunc)
- func (ut *UpgradeTable) RegisterFS(fs fullFS)
- func (ut *UpgradeTable) RegisterFSPath(fs fullFS, dir string)
- type ZeroLogSettings
Constants ¶
const ( ContextKeyDatabaseTransaction contextKey = iota ContextKeyDoTxnCallerSkip )
Variables ¶
var ( ErrTxn = errors.New("transaction") ErrTxnBegin = fmt.Errorf("%w: begin", ErrTxn) ErrTxnCommit = fmt.Errorf("%w: commit", ErrTxn) )
Functions ¶
func NumPtr ¶
func NumPtr[T constraints.Integer | constraints.Float](val T) *T
NumPtr returns a pointer to the given number, or nil if the number is zero.
func ScanDataStruct ¶
func ScanDataStruct[T NewableDataStruct[T]](rows Scannable) (T, error)
func ScanSingleColumn ¶
func StrPtr ¶
StrPtr returns a pointer to the given string, or nil if the string is empty.
func ValueOrErr ¶
ValueOrErr is a helper function that returns the value if err is nil, or returns nil and the error if err is not nil. It can be used to avoid `if err != nil { return nil, err }` boilerplate in certain cases like DataStruct.Scan implementations.
Types ¶
type Config ¶
type Config struct { PoolConfig `yaml:",inline"` ReadOnlyPool PoolConfig `yaml:"ro_pool"` }
type DataStruct ¶
DataStruct is an interface for structs that represent a single database row.
type Database ¶
type Database struct { LoggingDB loggingDB RawDB *sql.DB ReadOnlyDB *sql.DB Owner string VersionTable string Log DatabaseLogger Dialect Dialect UpgradeTable UpgradeTable IgnoreForeignTables bool IgnoreUnsupportedDatabase bool }
func NewFromConfig ¶
func NewFromConfig(owner string, cfg Config, logger DatabaseLogger) (*Database, error)
func NewWithDB ¶
func NewWithDialect ¶
func (*Database) BeginTx ¶
func (*Database) Child ¶
func (db *Database) Child(versionTable string, upgradeTable UpgradeTable, log DatabaseLogger) *Database
func (*Database) Close ¶
func (*Database) ColumnExists ¶
func (db *Database) ColumnExists(ctx context.Context, table, column string) (exists bool, err error)
func (*Database) Configure ¶
func (*Database) Conn ¶
func (*Database) DoTxn ¶
func (db *Database) DoTxn(ctx context.Context, opts *sql.TxOptions, fn func(ctx context.Context) error) error
func (*Database) Exec ¶
func (*Database) Query ¶
func (*Database) QueryRow ¶
func (*Database) TableExists ¶
func (*Database) Upgrade ¶
type DatabaseLogger ¶
type DatabaseLogger interface { QueryTiming(ctx context.Context, method, query string, args []any, nrows int, duration time.Duration, err error) WarnUnsupportedVersion(current, compat, latest int) PrepareUpgrade(current, compat, latest int) DoUpgrade(from, to int, message string, txn bool) // Deprecated: legacy warning method, return errors instead Warn(msg string, args ...any) }
var NoopLogger DatabaseLogger = &noopLogger{}
func ZeroLogger ¶
func ZeroLogger(log zerolog.Logger, cfg ...ZeroLogSettings) DatabaseLogger
func ZeroLoggerPtr ¶
func ZeroLoggerPtr(log *zerolog.Logger, cfg ...ZeroLogSettings) DatabaseLogger
type Dialect ¶
type Dialect int
func ParseDialect ¶
func (Dialect) String ¶
type Execable ¶
type Execable interface { ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) QueryContext(ctx context.Context, query string, args ...any) (Rows, error) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row }
type JSON ¶
type JSON struct { Data any }
JSON is a utility type for using arbitrary JSON data as values in database Exec and Scan calls.
func (JSON) Scan ¶
func (JSON) Value ¶
type LoggingExecable ¶
type LoggingExecable struct { UnderlyingExecable UnderlyingExecable // contains filtered or unexported fields }
LoggingExecable is a wrapper for anything with database Exec methods (i.e. sql.Conn, sql.DB and sql.Tx) that can preprocess queries (e.g. replacing $ with ? on SQLite) and log query durations.
func (*LoggingExecable) ExecContext ¶
func (le *LoggingExecable) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
func (*LoggingExecable) QueryContext ¶
func (le *LoggingExecable) QueryContext(ctx context.Context, query string, args ...any) (Rows, error)
func (*LoggingExecable) QueryRowContext ¶
type LoggingRows ¶
type LoggingRows struct {
// contains filtered or unexported fields
}
func (*LoggingRows) Close ¶
func (lrs *LoggingRows) Close() error
func (*LoggingRows) ColumnTypes ¶
func (lrs *LoggingRows) ColumnTypes() ([]*sql.ColumnType, error)
func (*LoggingRows) Columns ¶
func (lrs *LoggingRows) Columns() ([]string, error)
func (*LoggingRows) Err ¶
func (lrs *LoggingRows) Err() error
func (*LoggingRows) Next ¶
func (lrs *LoggingRows) Next() bool
func (*LoggingRows) NextResultSet ¶
func (lrs *LoggingRows) NextResultSet() bool
func (*LoggingRows) Scan ¶
func (lrs *LoggingRows) Scan(dest ...any) error
type LoggingTxn ¶
type LoggingTxn struct { LoggingExecable UnderlyingTx *sql.Tx StartTime time.Time EndTime time.Time // contains filtered or unexported fields }
func (*LoggingTxn) Commit ¶
func (lt *LoggingTxn) Commit() error
func (*LoggingTxn) Rollback ¶
func (lt *LoggingTxn) Rollback() error
type NewableDataStruct ¶
type NewableDataStruct[T any] interface { DataStruct[T] New() T }
type PQErrorWithLine ¶
func (*PQErrorWithLine) Error ¶
func (pqe *PQErrorWithLine) Error() string
func (*PQErrorWithLine) Unwrap ¶
func (pqe *PQErrorWithLine) Unwrap() error
type PoolConfig ¶
type PoolConfig struct { Type string `yaml:"type"` URI string `yaml:"uri"` MaxOpenConns int `yaml:"max_open_conns"` MaxIdleConns int `yaml:"max_idle_conns"` ConnMaxIdleTime string `yaml:"conn_max_idle_time"` ConnMaxLifetime string `yaml:"conn_max_lifetime"` }
type QueryHelper ¶
type QueryHelper[T DataStruct[T]] struct { // contains filtered or unexported fields }
QueryHelper is a generic helper struct for SQL query execution boilerplate.
After implementing the Scan and Init methods in a data struct, the query helper allows writing query functions in a single line.
func MakeQueryHelper ¶
func MakeQueryHelper[T DataStruct[T]](db *Database, new func(qh *QueryHelper[T]) T) *QueryHelper[T]
func (*QueryHelper[T]) Exec ¶
Exec executes a query with ExecContext and returns the error.
It omits the sql.Result return value, as it is rarely used. When the result is wanted, use `qh.GetDB().Exec(...)` instead, which is otherwise equivalent.
func (*QueryHelper[T]) GetDB ¶
func (qh *QueryHelper[T]) GetDB() *Database
func (*QueryHelper[T]) New ¶
func (qh *QueryHelper[T]) New() T
func (*QueryHelper[T]) QueryMany ¶
QueryMany executes a query with QueryContext, uses the associated DataStruct to scan each row, and returns the values. If the query returns no rows, it returns a non-nil zero-length slice and no error.
func (*QueryHelper[T]) QueryOne ¶
func (qh *QueryHelper[T]) QueryOne(ctx context.Context, query string, args ...any) (val T, err error)
QueryOne executes a query with QueryRowContext, uses the associated DataStruct to scan it, and returns the value. If the query returns no rows, it returns nil and no error.
type RowIter ¶
type RowIter[T any] interface { // Iter iterates over the rows and calls the given function for each row. // // If the function returns false, the iteration is stopped. // If the function returns an error, the iteration is stopped and the error is // returned. Iter(func(T) (bool, error)) error // AsList collects all rows into a slice. AsList() ([]T, error) }
RowIter is a wrapper for Rows that allows conveniently iterating over rows with a predefined scanner function.
func NewRowIter ¶
NewRowIter creates a new RowIter from the given Rows and scanner function.
type Rows ¶
type Rows interface { Close() error ColumnTypes() ([]*sql.ColumnType, error) Columns() ([]string, error) Err() error Next() bool NextResultSet() bool Scan(...any) error }
type Scannable ¶
type Transaction ¶
type UnderlyingExecable ¶
type UnderlyingExecable interface { ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row }
type UpgradeTable ¶
type UpgradeTable []upgrade
func (*UpgradeTable) Register ¶
func (ut *UpgradeTable) Register(from, to, compat int, message string, txn bool, fn upgradeFunc)
func (*UpgradeTable) RegisterFS ¶
func (ut *UpgradeTable) RegisterFS(fs fullFS)
func (*UpgradeTable) RegisterFSPath ¶
func (ut *UpgradeTable) RegisterFSPath(fs fullFS, dir string)
type ZeroLogSettings ¶
type ZeroLogSettings struct { CallerSkipFrame int Caller bool // TraceLogAllQueries specifies whether or not all queries should be logged // at the TRACE level. TraceLogAllQueries bool }
Source Files ¶
connlog.go database.go iter.go json.go log.go queryhelper.go transaction.go upgrades.go upgradetable.go
Directories ¶
Path | Synopsis |
---|---|
dbutil/litestream |
- Version
- v0.3.0
- Published
- Jan 16, 2024
- Platform
- darwin/amd64
- Imports
- 18 packages
- Last checked
- 3 hours ago –
Tools for package owners.