upgrade deps; rewrite smtp session
This commit is contained in:
11
vendor/go.mau.fi/util/dbutil/database.go
vendored
11
vendor/go.mau.fi/util/dbutil/database.go
vendored
@@ -183,11 +183,12 @@ type Config struct {
|
||||
func (db *Database) Close() error {
|
||||
err := db.RawDB.Close()
|
||||
if db.ReadOnlyDB != nil {
|
||||
err2 := db.ReadOnlyDB.Close()
|
||||
if err == nil {
|
||||
err = fmt.Errorf("closing read-only db failed: %w", err2)
|
||||
} else {
|
||||
err = fmt.Errorf("%w (closing read-only db also failed: %v)", err, err2)
|
||||
if err2 := db.ReadOnlyDB.Close(); err2 != nil {
|
||||
if err == nil {
|
||||
err = fmt.Errorf("closing read-only db failed: %w", err2)
|
||||
} else {
|
||||
err = fmt.Errorf("%w (closing read-only db also failed: %v)", err, err2)
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
||||
102
vendor/go.mau.fi/util/dbutil/iter.go
vendored
102
vendor/go.mau.fi/util/dbutil/iter.go
vendored
@@ -6,6 +6,10 @@
|
||||
|
||||
package dbutil
|
||||
|
||||
import "errors"
|
||||
|
||||
var ErrAlreadyIterated = errors.New("this iterator has been already iterated")
|
||||
|
||||
// RowIter is a wrapper for [Rows] that allows conveniently iterating over rows
|
||||
// with a predefined scanner function.
|
||||
type RowIter[T any] interface {
|
||||
@@ -20,16 +24,41 @@ type RowIter[T any] interface {
|
||||
AsList() ([]T, error)
|
||||
}
|
||||
|
||||
type ConvertRowFn[T any] func(Scannable) (T, error)
|
||||
|
||||
// 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 ..."),
|
||||
// )
|
||||
// }
|
||||
func (crf ConvertRowFn[T]) NewRowIter(rows Rows, err error) RowIter[T] {
|
||||
return NewRowIterWithError(rows, crf, err)
|
||||
}
|
||||
|
||||
type rowIterImpl[T any] struct {
|
||||
Rows
|
||||
ConvertRow func(Scannable) (T, error)
|
||||
ConvertRow ConvertRowFn[T]
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
// NewRowIter creates a new RowIter from the given Rows and scanner function.
|
||||
func NewRowIter[T any](rows Rows, convertFn func(Scannable) (T, error)) RowIter[T] {
|
||||
func NewRowIter[T any](rows Rows, convertFn ConvertRowFn[T]) RowIter[T] {
|
||||
return &rowIterImpl[T]{Rows: rows, ConvertRow: convertFn}
|
||||
}
|
||||
|
||||
// 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 NewRowIterWithError[T any](rows Rows, convertFn ConvertRowFn[T], err error) RowIter[T] {
|
||||
return &rowIterImpl[T]{Rows: rows, ConvertRow: convertFn, err: err}
|
||||
}
|
||||
|
||||
func ScanSingleColumn[T any](rows Scannable) (val T, err error) {
|
||||
err = rows.Scan(&val)
|
||||
return
|
||||
@@ -46,21 +75,32 @@ func ScanDataStruct[T NewableDataStruct[T]](rows Scannable) (T, error) {
|
||||
}
|
||||
|
||||
func (i *rowIterImpl[T]) Iter(fn func(T) (bool, error)) error {
|
||||
if i == nil || i.Rows == nil {
|
||||
if i == nil {
|
||||
return nil
|
||||
} else if i.Rows == nil || i.err != nil {
|
||||
return i.err
|
||||
}
|
||||
defer i.Rows.Close()
|
||||
|
||||
for i.Rows.Next() {
|
||||
if item, err := i.ConvertRow(i.Rows); err != nil {
|
||||
i.err = err
|
||||
return err
|
||||
} else if cont, err := fn(item); err != nil {
|
||||
i.err = err
|
||||
return err
|
||||
} else if !cont {
|
||||
break
|
||||
}
|
||||
}
|
||||
return i.Rows.Err()
|
||||
|
||||
err := i.Rows.Err()
|
||||
if err != nil {
|
||||
i.err = err
|
||||
} else {
|
||||
i.err = ErrAlreadyIterated
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *rowIterImpl[T]) AsList() (list []T, err error) {
|
||||
@@ -70,3 +110,57 @@ func (i *rowIterImpl[T]) AsList() (list []T, err error) {
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func RowIterAsMap[T any, Key comparable, Value any](ri RowIter[T], getKeyValue func(T) (Key, Value)) (map[Key]Value, error) {
|
||||
m := make(map[Key]Value)
|
||||
err := ri.Iter(func(item T) (bool, error) {
|
||||
k, v := getKeyValue(item)
|
||||
m[k] = v
|
||||
return true, nil
|
||||
})
|
||||
return m, err
|
||||
}
|
||||
|
||||
type sliceIterImpl[T any] struct {
|
||||
items []T
|
||||
err error
|
||||
}
|
||||
|
||||
func NewSliceIter[T any](items []T) RowIter[T] {
|
||||
return &sliceIterImpl[T]{items: items}
|
||||
}
|
||||
|
||||
func NewSliceIterWithError[T any](items []T, err error) RowIter[T] {
|
||||
return &sliceIterImpl[T]{items: items, err: err}
|
||||
}
|
||||
|
||||
func (i *sliceIterImpl[T]) Iter(fn func(T) (bool, error)) error {
|
||||
if i == nil {
|
||||
return nil
|
||||
} else if i.err != nil {
|
||||
return i.err
|
||||
}
|
||||
|
||||
for _, item := range i.items {
|
||||
if cont, err := fn(item); err != nil {
|
||||
i.err = err
|
||||
return err
|
||||
} else if !cont {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
i.err = ErrAlreadyIterated
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *sliceIterImpl[T]) AsList() ([]T, error) {
|
||||
if i == nil {
|
||||
return nil, nil
|
||||
} else if i.err != nil {
|
||||
return nil, i.err
|
||||
}
|
||||
|
||||
i.err = ErrAlreadyIterated
|
||||
return i.items, nil
|
||||
}
|
||||
|
||||
2
vendor/go.mau.fi/util/dbutil/upgrades.go
vendored
2
vendor/go.mau.fi/util/dbutil/upgrades.go
vendored
@@ -183,7 +183,7 @@ func (db *Database) Upgrade(ctx context.Context) error {
|
||||
doUpgrade := func(ctx context.Context) error {
|
||||
err = upgradeItem.fn(ctx, db)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to run upgrade #%d: %w", version, err)
|
||||
return fmt.Errorf("failed to run upgrade v%d->v%d: %w", version, upgradeItem.upgradesTo, err)
|
||||
}
|
||||
version = upgradeItem.upgradesTo
|
||||
logVersion = version
|
||||
|
||||
Reference in New Issue
Block a user