Refactor DB connection settings

This commit is contained in:
Jan Eitzinger 2023-06-01 08:03:12 +02:00
parent f2fa3ebf77
commit 0f87f651f9

View File

@ -5,15 +5,11 @@
package repository package repository
import ( import (
"database/sql"
"fmt"
"log" "log"
"sync" "sync"
"time" "time"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
"github.com/mattn/go-sqlite3"
"github.com/qustavo/sqlhooks/v2"
) )
var ( var (
@ -26,35 +22,56 @@ type DBConnection struct {
Driver string Driver string
} }
type DatabaseOptions struct {
URL string
MaxOpenConnections int
MaxIdleConnections int
ConnectionMaxLifetime time.Duration
ConnectionMaxIdleTime time.Duration
}
func Connect(driver string, db string) { func Connect(driver string, db string) {
var err error var err error
var dbHandle *sqlx.DB var dbHandle *sqlx.DB
dbConnOnce.Do(func() { dbConnOnce.Do(func() {
if driver == "sqlite3" { opts := DatabaseOptions{
sql.Register("sqlite3WithHooks", sqlhooks.Wrap(&sqlite3.SQLiteDriver{}, &Hooks{})) URL: db,
dbHandle, err = sqlx.Open("sqlite3WithHooks", fmt.Sprintf("%s?_foreign_keys=on", db)) MaxOpenConnections: 5,
// dbHandle, err = sqlx.Open("sqlite3", fmt.Sprintf("%s?_foreign_keys=on", db)) MaxIdleConnections: 5,
ConnectionMaxLifetime: time.Hour,
ConnectionMaxIdleTime: time.Hour,
}
switch driver {
case "sqlite3":
// sql.Register("sqlite3WithHooks", sqlhooks.Wrap(&sqlite3.SQLiteDriver{}, &Hooks{}))
// - Set WAL mode (not strictly necessary each time because it's persisted in the database, but good for first run)
// - Set busy timeout, so concurrent writers wait on each other instead of erroring immediately
// - Enable foreign key checks
opts.URL += "?_journal=WAL&_timeout=5000&_fk=true"
// dbHandle, err = sqlx.Open("sqlite3WithHooks", fmt.Sprintf("%s?_foreign_keys=on", db))
dbHandle, err = sqlx.Open("sqlite3", opts.URL)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
case "mysql":
// sqlite does not multithread. Having more than one connection open would just mean opts.URL += "?multiStatements=true"
// waiting for locks. dbHandle, err = sqlx.Open("mysql", opts.URL)
dbHandle.SetMaxOpenConns(1)
} else if driver == "mysql" {
dbHandle, err = sqlx.Open("mysql", fmt.Sprintf("%s?multiStatements=true", db))
if err != nil { if err != nil {
log.Fatalf("sqlx.Open() error: %v", err) log.Fatalf("sqlx.Open() error: %v", err)
} }
default:
dbHandle.SetConnMaxLifetime(time.Minute * 3)
dbHandle.SetMaxOpenConns(10)
dbHandle.SetMaxIdleConns(10)
} else {
log.Fatalf("unsupported database driver: %s", driver) log.Fatalf("unsupported database driver: %s", driver)
} }
dbHandle.SetMaxOpenConns(opts.MaxOpenConnections)
dbHandle.SetMaxIdleConns(opts.MaxIdleConnections)
dbHandle.SetConnMaxLifetime(opts.ConnectionMaxLifetime)
dbHandle.SetConnMaxIdleTime(opts.ConnectionMaxIdleTime)
dbConnInstance = &DBConnection{DB: dbHandle, Driver: driver} dbConnInstance = &DBConnection{DB: dbHandle, Driver: driver}
err = checkDBVersion(driver, dbHandle.DB) err = checkDBVersion(driver, dbHandle.DB)
if err != nil { if err != nil {