refactor to MariaDB-only runtime and simplify PriceForge

This commit is contained in:
2026-02-07 21:38:55 +03:00
parent 20309d1f0e
commit 005478ac6b
37 changed files with 302 additions and 10324 deletions

View File

@@ -3,13 +3,11 @@ package db
import (
"context"
"fmt"
"sync"
"time"
"git.mchus.pro/mchus/priceforge/internal/localdb"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"sync"
"time"
)
const (
@@ -32,20 +30,22 @@ type ConnectionStatus struct {
// ConnectionManager manages database connections with thread-safety and connection pooling
type ConnectionManager struct {
localDB *localdb.LocalDB // for getting DSN from settings
mu sync.RWMutex // protects db and state
db *gorm.DB // current connection (nil if not connected)
lastError error // last connection error
lastCheck time.Time // time of last check/attempt
connectTimeout time.Duration // timeout for connection (default: 5s)
pingInterval time.Duration // minimum interval between pings (default: 30s)
reconnectCooldown time.Duration // pause after failed attempt (default: 10s)
dsn string
dsnHost string
mu sync.RWMutex // protects db and state
db *gorm.DB // current connection (nil if not connected)
lastError error // last connection error
lastCheck time.Time // time of last check/attempt
connectTimeout time.Duration // timeout for connection (default: 5s)
pingInterval time.Duration // minimum interval between pings (default: 30s)
reconnectCooldown time.Duration // pause after failed attempt (default: 10s)
}
// NewConnectionManager creates a new ConnectionManager instance
func NewConnectionManager(localDB *localdb.LocalDB) *ConnectionManager {
func NewConnectionManager(dsn string, dsnHost string) *ConnectionManager {
return &ConnectionManager{
localDB: localDB,
dsn: dsn,
dsnHost: dsnHost,
connectTimeout: defaultConnectTimeout,
pingInterval: defaultPingInterval,
reconnectCooldown: defaultReconnectCooldown,
@@ -58,9 +58,8 @@ func NewConnectionManager(localDB *localdb.LocalDB) *ConnectionManager {
// GetDB returns the current database connection, establishing it if needed
// Thread-safe and respects connection cooldowns
func (cm *ConnectionManager) GetDB() (*gorm.DB, error) {
// Handle case where localDB is nil
if cm.localDB == nil {
return nil, fmt.Errorf("local database not initialized")
if cm.dsn == "" {
return nil, fmt.Errorf("database DSN is empty")
}
// First check if we already have a valid connection
@@ -109,18 +108,12 @@ func (cm *ConnectionManager) GetDB() (*gorm.DB, error) {
// connect establishes a new database connection
func (cm *ConnectionManager) connect() error {
// Get DSN from local settings
dsn, err := cm.localDB.GetDSN()
if err != nil {
return fmt.Errorf("getting DSN: %w", err)
}
// Create context with timeout
ctx, cancel := context.WithTimeout(context.Background(), cm.connectTimeout)
defer cancel()
// Open database connection
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
db, err := gorm.Open(mysql.Open(cm.dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
@@ -261,13 +254,10 @@ func (cm *ConnectionManager) GetStatus() ConnectionStatus {
status.LastError = cm.lastError.Error()
}
// Extract host from DSN for display
if cm.localDB != nil {
if dsn, err := cm.localDB.GetDSN(); err == nil {
// Parse DSN to extract host:port
// Format: user:password@tcp(host:port)/database?...
status.DSNHost = extractHostFromDSN(dsn)
}
if cm.dsnHost != "" {
status.DSNHost = cm.dsnHost
} else {
status.DSNHost = extractHostFromDSN(cm.dsn)
}
return status