package dbutil
import "go.mau.fi/util/dbutil"
Index ¶
- Constants
- Variables
- func ConvertedPtr[Input Zeroable, Output any](val Input, converter func(Input) Output) *Output
- func NumPtr[T constraints.Integer | constraints.Float](val T) *T
- func RowIterAsMap[T any, Key comparable, Value any](ri RowIter[T], getKeyValue func(T) (Key, Value)) (map[Key]Value, error)
- 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 UnixMilliPtr(val time.Time) *int64
- func UnixPtr(val time.Time) *int64
- func UntypedNil[T any](val *T) any
- func ValueOrErr[T any](val *T, err error) (*T, error)
- type Config
- type ConvertRowFn
- 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
- func JSONPtr[T any](val *T) JSON
- func (j JSON) Scan(i any) error
- func (j JSON) Value() (driver.Value, error)
- 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
- func NewRowIter[T any](rows Rows, convertFn ConvertRowFn[T]) RowIter[T]
- func NewRowIterWithError[T any](rows Rows, convertFn ConvertRowFn[T], err error) RowIter[T]
- func NewSliceIter[T any](items []T) RowIter[T]
- func NewSliceIterWithError[T any](items []T, err error) RowIter[T]
- 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
- type Zeroable
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 ConvertedPtr ¶
ConvertedPtr returns a pointer to the converted version of the given value, or nil if the input is zero.
This is primarily meant for time.Time, but it can be used with any type that has implements `IsZero() bool`.
yourTime := time.Now() unixMSPtr := dbutil.TimePtr(yourTime, time.Time.UnixMilli)
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 RowIterAsMap ¶
func RowIterAsMap[T any, Key comparable, Value any](ri RowIter[T], getKeyValue func(T) (Key, Value)) (map[Key]Value, error)
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 UnixMilliPtr ¶
UnixMilliPtr returns a pointer to the given time as unix milliseconds, or nil if the time is zero.
func UnixPtr ¶
UnixPtr returns a pointer to the given time as unix seconds, or nil if the time is zero.
func UntypedNil ¶
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 ConvertRowFn ¶
func (ConvertRowFn[T]) NewRowIter ¶
func (crf ConvertRowFn[T]) NewRowIter(rows Rows, err error) RowIter[T]
NewRowIter is a proxy for NewRowIterWithError for more convenient usage.
For example:
func exampleConvertRowFn(rows Scannable) (*YourType, error) { ... } func exampleFunction() { iter := dbutil.ConvertRowFn[*YourType](exampleConvertRowFn).NewRowIter( db.Query("SELECT ..."), ) }
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 JSONPtr ¶
JSONPtr is a convenience function for wrapping a pointer to a value in the JSON utility, but removing typed nils (i.e. preventing nils from turning into the string "null" in the database).
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 ¶
func NewRowIter[T any](rows Rows, convertFn ConvertRowFn[T]) RowIter[T]
NewRowIter creates a new RowIter from the given Rows and scanner function.
func NewRowIterWithError ¶
func NewRowIterWithError[T any](rows Rows, convertFn ConvertRowFn[T], err error) RowIter[T]
NewRowIterWithError creates a new RowIter from the given Rows and scanner function with default error. If not nil, it will be returned without calling iterator function.
func NewSliceIter ¶
func NewSliceIterWithError ¶
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 }
type Zeroable ¶
type Zeroable interface { IsZero() 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.4.1
- Published
- Mar 16, 2024
- Platform
- js/wasm
- Imports
- 19 packages
- Last checked
- 10 hours ago –
Tools for package owners.