package psql import ( "fmt" "log" "os" "os/exec" "path" "path/filepath" "runtime" "baal.ar76.eu/x/pub/multisql/cfg" ) type Instance struct { outdir string scripts []string passfile string psqlExe string conn cfg.Connection verbose bool } type Result struct { Script string Err error } func Create(passfile string, outdir string, scripts []string, conn cfg.Connection, psqlExe string, verbose bool) (instnace Instance) { instnace = Instance{ outdir: outdir, scripts: scripts, passfile: passfile, conn: conn, psqlExe: psqlExe, verbose: verbose, } return instnace } func (self Instance) Exec(result chan<- Result) { absPassFile := "" if self.passfile != "" { var err error absPassFile, err = filepath.Abs(self.passfile) if err != nil { result <- Result{ Script: "*", Err: fmt.Errorf("problem ze zbudowaniem ściężki do pliku haseł: %w", err), } return } } connString := fmt.Sprintf("host=%s port=%d dbname=%s user=%s", self.conn.Host, self.conn.Port, self.conn.DbName, self.conn.User) for _, scr := range self.scripts { srcName := path.Base(scr) outdir := path.Join(self.outdir, srcName) err := os.Mkdir(outdir, 0o775) if err != nil { result <- Result{ Script: scr, Err: err, } continue } err = self.cmdPsql(outdir, connString, scr, absPassFile) result <- Result{ Script: scr, Err: err, } } close(result) } func (self Instance) cmdPsql(outdir string, connString string, script string, passfile string) error { absScript, err := filepath.Abs(script) if err != nil { return fmt.Errorf("problem ze zbudowaniem ściezki do skryptu: %w", err) } psqlExe := "psql" if runtime.GOOS == "windows" { psqlExe = "psql.exe" } if self.psqlExe != "" { psqlExe = self.psqlExe } stdoutFile := path.Join(outdir, "stdout.txt") stderrFile := path.Join(outdir, "stderr.txt") logFile := "log.txt" fhOut, err := os.Create(stdoutFile) if err != nil { return fmt.Errorf("Problem utworzenie pliku wyników: %v", err) } defer fhOut.Close() fhErr, err := os.Create(stderrFile) if err != nil { return fmt.Errorf("Problem utworzenie pliku błędów: %v", err) } defer fhErr.Close() cmd := exec.Command(psqlExe, "-w", "-f", absScript, "-L", logFile, connString, ) cmd.Stderr = fhErr cmd.Stdout = fhOut cmd.Dir = outdir if passfile != "" { env := os.Environ() env = append(env, "PGPASSFILE=" + passfile) cmd.Env = env } if self.verbose { log.Printf("Uruchamiam %s", cmd.String()) } err = cmd.Run() if err != nil { return fmt.Errorf("Błąd uruchamiania psql: %v", err) } return nil }