package psql import ( "fmt" "log" "os" "os/exec" "path" "path/filepath" "runtime" "baal.ar76.eu/x/pub/multisql/cfg" "baal.ar76.eu/x/pub/multisql/pass" ) type Instance struct { outdir string scripts []string pasdb *pass.PassDb psqlExe string conn cfg.Connection verbose bool } type Result struct { Script string Err error } func Create(passdb *pass.PassDb, outdir string, scripts []string, conn cfg.Connection, psqlExe string, verbose bool) (instnace Instance) { instnace = Instance{ outdir: outdir, scripts: scripts, pasdb: passdb, conn: conn, psqlExe: psqlExe, verbose: verbose, } return instnace } func (self Instance) Exec(result chan<- Result) { 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 } password := self.pasdb.FindPassword(self.conn.Host, self.conn.Port, self.conn.DbName, self.conn.User) err = self.cmdPsql(outdir, connString, scr, password) result <- Result{ Script: scr, Err: err, } } close(result) } func (self Instance) cmdPsql(outdir string, connString string, script string, password 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 password != "" { env := os.Environ() env = append(env, "PGPASSWORD="+password) 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 }