@@ -14,6 +14,7 @@ import (
|
||||
|
||||
type Store struct {
|
||||
mu sync.RWMutex
|
||||
syncMu sync.Mutex
|
||||
cfg *config.Config
|
||||
path string
|
||||
db *sql.DB
|
||||
@@ -114,6 +115,80 @@ func (s *Store) Path() string {
|
||||
return s.path
|
||||
}
|
||||
|
||||
func (s *Store) ReconfigureDatabase(cfg *config.Config) error {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
path := cfg.Database.SQLitePath
|
||||
if strings.TrimSpace(path) == "" {
|
||||
path = filepath.Join(cfg.StorageDir, "unified.sqlite")
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o750); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(cfg.StorageDir, 0o750); err != nil {
|
||||
return err
|
||||
}
|
||||
localCfg := cfg.Database
|
||||
localCfg.Provider = "sqlite"
|
||||
localCfg.SQLitePath = path
|
||||
local, localDialect, err := openSQLDatabase(localCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
local.SetMaxOpenConns(1)
|
||||
if err := s.migrate(local, localDialect); err != nil {
|
||||
_ = local.Close()
|
||||
return err
|
||||
}
|
||||
var remote *sql.DB
|
||||
var remoteDialect dialect
|
||||
if strings.EqualFold(cfg.Database.Provider, "mysql") {
|
||||
remote, remoteDialect, err = openSQLDatabase(cfg.Database)
|
||||
if err != nil {
|
||||
_ = local.Close()
|
||||
return err
|
||||
}
|
||||
if err := s.migrate(remote, remoteDialect); err != nil {
|
||||
_ = remote.Close()
|
||||
_ = local.Close()
|
||||
return err
|
||||
}
|
||||
}
|
||||
s.mu.Lock()
|
||||
oldLocal := s.localDB
|
||||
oldRemote := s.remoteDB
|
||||
s.cfg.Database = cfg.Database
|
||||
s.path = path
|
||||
s.localDB = local
|
||||
s.localDialect = localDialect
|
||||
s.remoteDB = remote
|
||||
s.remoteDialect = remoteDialect
|
||||
s.status.ConfigProvider = cfg.Database.Provider
|
||||
s.status.SQLiteReady = true
|
||||
s.status.RemoteReady = remote != nil
|
||||
s.status.LastError = ""
|
||||
s.status.FailoverActive = false
|
||||
if remote != nil {
|
||||
s.db = remote
|
||||
s.dialect = remoteDialect
|
||||
s.status.ActiveProvider = "mysql"
|
||||
} else {
|
||||
s.db = local
|
||||
s.dialect = localDialect
|
||||
s.status.ActiveProvider = "sqlite"
|
||||
}
|
||||
s.status.LastRecoveredAt = Now()
|
||||
s.mu.Unlock()
|
||||
if oldRemote != nil && oldRemote != oldLocal && oldRemote != remote {
|
||||
_ = oldRemote.Close()
|
||||
}
|
||||
if oldLocal != nil && oldLocal != local {
|
||||
_ = oldLocal.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) active() (*sql.DB, dialect) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
Reference in New Issue
Block a user