updated deps

This commit is contained in:
Aine
2023-06-16 16:29:28 +03:00
parent 4c11919a46
commit f9d05d94c9
64 changed files with 12175 additions and 5221 deletions

View File

@@ -71,8 +71,12 @@ type loggingDB struct {
}
func (ld *loggingDB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*LoggingTxn, error) {
targetDB := ld.db.RawDB
if opts != nil && opts.ReadOnly && ld.db.ReadOnlyDB != nil {
targetDB = ld.db.ReadOnlyDB
}
start := time.Now()
tx, err := ld.db.RawDB.BeginTx(ctx, opts)
tx, err := targetDB.BeginTx(ctx, opts)
ld.db.Log.QueryTiming(ctx, "Begin", "", nil, -1, time.Since(start), err)
if err != nil {
return nil, err
@@ -102,7 +106,10 @@ type LoggingTxn struct {
func (lt *LoggingTxn) Commit() error {
start := time.Now()
err := lt.UnderlyingTx.Commit()
lt.endLog()
lt.EndTime = time.Now()
if !lt.noTotalLog {
lt.db.Log.QueryTiming(lt.ctx, "<Transaction>", "", nil, -1, lt.EndTime.Sub(lt.StartTime), nil)
}
lt.db.Log.QueryTiming(lt.ctx, "Commit", "", nil, -1, time.Since(start), err)
return err
}
@@ -110,16 +117,12 @@ func (lt *LoggingTxn) Commit() error {
func (lt *LoggingTxn) Rollback() error {
start := time.Now()
err := lt.UnderlyingTx.Rollback()
lt.endLog()
lt.db.Log.QueryTiming(lt.ctx, "Rollback", "", nil, -1, time.Since(start), err)
return err
}
func (lt *LoggingTxn) endLog() {
lt.EndTime = time.Now()
if !lt.noTotalLog {
lt.db.Log.QueryTiming(lt.ctx, "<Transaction>", "", nil, -1, lt.EndTime.Sub(lt.StartTime), nil)
}
lt.db.Log.QueryTiming(lt.ctx, "Rollback", "", nil, -1, time.Since(start), err)
return err
}
type LoggingRows struct {

View File

@@ -10,6 +10,7 @@ import (
"context"
"database/sql"
"fmt"
"net/url"
"regexp"
"strings"
"time"
@@ -35,12 +36,13 @@ func (dialect Dialect) String() string {
}
func ParseDialect(engine string) (Dialect, error) {
switch strings.ToLower(engine) {
case "postgres", "postgresql", "pgx":
engine = strings.ToLower(engine)
if strings.HasPrefix(engine, "postgres") || engine == "pgx" {
return Postgres, nil
case "sqlite3", "sqlite", "litestream", "sqlite3-fk-wal":
} else if strings.HasPrefix(engine, "sqlite") || strings.HasPrefix(engine, "litestream") {
return SQLite, nil
default:
} else {
return DialectUnknown, fmt.Errorf("unknown dialect '%s'", engine)
}
}
@@ -109,6 +111,7 @@ var (
type Database struct {
loggingDB
RawDB *sql.DB
ReadOnlyDB *sql.DB
Owner string
VersionTable string
Log DatabaseLogger
@@ -171,10 +174,11 @@ func NewWithDialect(uri, rawDialect string) (*Database, error) {
if err != nil {
return nil, err
}
return NewWithDB(db, rawDialect)
}
type Config struct {
type PoolConfig struct {
Type string `yaml:"type"`
URI string `yaml:"uri"`
@@ -185,54 +189,101 @@ type Config struct {
ConnMaxLifetime string `yaml:"conn_max_lifetime"`
}
type Config struct {
PoolConfig `yaml:",inline"`
ReadOnlyPool PoolConfig `yaml:"ro_pool"`
}
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", err)
} else {
err = fmt.Errorf("%w (closing read-only db also failed: %v)", err, err2)
}
}
return err
}
func (db *Database) Configure(cfg Config) error {
db.RawDB.SetMaxOpenConns(cfg.MaxOpenConns)
db.RawDB.SetMaxIdleConns(cfg.MaxIdleConns)
if err := db.configure(db.ReadOnlyDB, cfg.ReadOnlyPool); err != nil {
return err
}
return db.configure(db.RawDB, cfg.PoolConfig)
}
func (db *Database) configure(rawDB *sql.DB, cfg PoolConfig) error {
if rawDB == nil {
return nil
}
rawDB.SetMaxOpenConns(cfg.MaxOpenConns)
rawDB.SetMaxIdleConns(cfg.MaxIdleConns)
if len(cfg.ConnMaxIdleTime) > 0 {
maxIdleTimeDuration, err := time.ParseDuration(cfg.ConnMaxIdleTime)
if err != nil {
return fmt.Errorf("failed to parse max_conn_idle_time: %w", err)
}
db.RawDB.SetConnMaxIdleTime(maxIdleTimeDuration)
rawDB.SetConnMaxIdleTime(maxIdleTimeDuration)
}
if len(cfg.ConnMaxLifetime) > 0 {
maxLifetimeDuration, err := time.ParseDuration(cfg.ConnMaxLifetime)
if err != nil {
return fmt.Errorf("failed to parse max_conn_idle_time: %w", err)
}
db.RawDB.SetConnMaxLifetime(maxLifetimeDuration)
rawDB.SetConnMaxLifetime(maxLifetimeDuration)
}
return nil
}
func NewFromConfig(owner string, cfg Config, logger DatabaseLogger) (*Database, error) {
dialect, err := ParseDialect(cfg.Type)
wrappedDB, err := NewWithDialect(cfg.URI, cfg.Type)
if err != nil {
return nil, err
}
conn, err := sql.Open(cfg.Type, cfg.URI)
if err != nil {
return nil, err
}
if logger == nil {
logger = NoopLogger
}
wrappedDB := &Database{
RawDB: conn,
Owner: owner,
Dialect: dialect,
Log: logger,
IgnoreForeignTables: true,
VersionTable: "version",
wrappedDB.Owner = owner
if logger != nil {
wrappedDB.Log = logger
}
if cfg.ReadOnlyPool.MaxOpenConns > 0 {
if cfg.ReadOnlyPool.Type == "" {
cfg.ReadOnlyPool.Type = cfg.Type
}
roUri := cfg.ReadOnlyPool.URI
if roUri == "" {
uriParts := strings.Split(cfg.URI, "?")
var qs url.Values
if len(uriParts) == 2 {
var err error
qs, err = url.ParseQuery(uriParts[1])
if err != nil {
return nil, err
}
qs.Del("_txlock")
}
qs.Set("_query_only", "true")
roUri = uriParts[0] + "?" + qs.Encode()
}
wrappedDB.ReadOnlyDB, err = sql.Open(cfg.ReadOnlyPool.Type, roUri)
if err != nil {
return nil, err
}
}
err = wrappedDB.Configure(cfg)
if err != nil {
return nil, err
}
wrappedDB.loggingDB.UnderlyingExecable = conn
wrappedDB.loggingDB.db = wrappedDB
return wrappedDB, nil
}

View File

@@ -80,6 +80,11 @@ func ZeroLoggerPtr(log *zerolog.Logger, cfg ...ZeroLogSettings) DatabaseLogger {
wrapped := &zeroLogger{l: log}
if len(cfg) > 0 {
wrapped.ZeroLogSettings = cfg[0]
} else {
wrapped.ZeroLogSettings = ZeroLogSettings{
CallerSkipFrame: 2, // Skip LoggingExecable.ExecContext and zeroLogger.QueryTiming
Caller: true,
}
}
return wrapped
}

View File

@@ -80,3 +80,14 @@ func (db *Database) DoTxn(ctx context.Context, opts *sql.TxOptions, fn func(ctx
log.Trace().Msg("Commit successful")
return nil
}
func (db *Database) Conn(ctx context.Context) ContextExecable {
if ctx == nil {
return db
}
txn, ok := ctx.Value(ContextKeyDatabaseTransaction).(Transaction)
if ok {
return txn
}
return db
}

54
vendor/maunium.net/go/mautrix/util/formatduration.go generated vendored Normal file
View File

@@ -0,0 +1,54 @@
// Copyright (c) 2023 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package util
import (
"errors"
"fmt"
"strings"
"time"
)
var Day = 24 * time.Hour
var Week = 7 * Day
func pluralize(value int, unit string) string {
if value == 1 {
return "1 " + unit
}
return fmt.Sprintf("%d %ss", value, unit)
}
func appendDurationPart(time, unit time.Duration, name string, parts *[]string) (remainder time.Duration) {
if time < unit {
return time
}
value := int(time / unit)
remainder = time % unit
*parts = append(*parts, pluralize(value, name))
return
}
func FormatDuration(d time.Duration) string {
if d < 0 {
panic(errors.New("FormatDuration: negative duration"))
} else if d < time.Second {
return "now"
}
parts := make([]string, 0, 2)
d = appendDurationPart(d, Week, "week", &parts)
d = appendDurationPart(d, Day, "day", &parts)
d = appendDurationPart(d, time.Hour, "hour", &parts)
d = appendDurationPart(d, time.Minute, "minute", &parts)
d = appendDurationPart(d, time.Second, "second", &parts)
if len(parts) > 2 {
parts[0] = strings.Join(parts[:len(parts)-1], ", ")
parts[1] = parts[len(parts)-1]
parts = parts[:2]
}
return strings.Join(parts, " and ")
}