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() }