multisql/mgr/mgr.go

133 lines
2.9 KiB
Go

package mgr
import (
"fmt"
"log"
"os"
"path"
"sync"
"time"
"baal.ar76.eu/x/pub/multisql/cfg"
"baal.ar76.eu/x/pub/multisql/pass"
"baal.ar76.eu/x/pub/multisql/psql"
)
type Manager struct {
config cfg.Config
runDir string
verbose bool
askPass bool
}
func Create(verbose bool, askPass bool, outdir string, config cfg.Config) (Manager, error) {
runDir := createRunDir(outdir)
manager := Manager{
config: config,
runDir: runDir,
verbose: verbose,
askPass: askPass,
}
return manager, nil
}
func createRunDir(out string) string {
t := time.Now()
dataPart := t.Format("2006-01-02T15_04_05")
newDir := fmt.Sprintf("%s-%d", dataPart, os.Getpid())
dir := path.Join(out, newDir)
return dir
}
func (self Manager) GetScripts() ([]string, error) {
entries, err := os.ReadDir(self.config.SqlDir)
if err != nil {
return nil, fmt.Errorf("błąd wczytywania skryptów: %w", err)
}
scripts := make([]string, 0, len(entries))
for _, e := range entries {
if e.IsDir() {
continue
}
scrpt := path.Join(self.config.SqlDir, e.Name())
_, err := os.Stat(scrpt)
if err != nil {
log.Printf("Skrypt zostanie pominięty z powodu błedu: %v\n", err)
continue
}
scripts = append(scripts, scrpt)
}
return scripts, err
}
func (self Manager) Run() error {
err := os.Mkdir(self.runDir, 0o755)
if err != nil {
return fmt.Errorf("błąd tworzenia katalogu z wynikami: %w", err)
}
scripts, err := self.GetScripts()
if err != nil {
return err
}
var passdb *pass.PassDb
if self.config.PassFile != "" {
password := pass.GetMasterPass(self.askPass)
passdb, err = pass.Load(self.config.PassFile, password)
if err != nil {
return err
}
}
var group sync.WaitGroup
for _, con := range self.config.Connections {
dbDir, err := self.createDirPerCon(con)
if err != nil {
log.Printf("Problem z utworzeniem katalogu wynikow dla połaczenie: %v", dbDir)
log.Printf("Pomijam połaczenie")
continue
}
group.Add(1)
stream := make(chan psql.Result)
go self.Logger(&group, stream, con)
sql := psql.Create(
passdb,
dbDir,
scripts,
con,
self.config.PsqlExec,
self.verbose,
)
go sql.Exec(stream)
}
group.Wait()
return nil
}
func (self Manager) createDirPerCon(con cfg.Connection) (string, error) {
dbDir := fmt.Sprintf("%s_%d_%s_%s", con.Host, con.Port, con.DbName, con.User)
dir := path.Join(self.runDir, dbDir)
err := os.Mkdir(dir, 0o755)
return dir, err
}
func (self Manager) Logger(group *sync.WaitGroup, stream <-chan psql.Result, con cfg.Connection) {
for event := range stream {
if event.Err != nil {
scr := path.Base(event.Script)
log.Printf("%s:%d:%s:%s Skrypt: %s Błąd: %v\n", con.Host, con.Port, con.DbName, con.User, scr, event.Err)
} else if self.verbose {
scr := path.Base(event.Script)
log.Printf("%s:%d:%s:%s Skrypt %s zakończony poprawnie\n", con.Host, con.Port, con.DbName, con.User, scr)
}
}
group.Done()
}