Рыба проекта. Минимальная функциональность
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package pgdump
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"git.tswf.io/infra/go-synapse-backupper/pkg/domain/pgdump"
|
||||
)
|
||||
|
||||
// adapter provides pg_dump functionality using the system's pg_dump binary.
|
||||
type adapter struct {
|
||||
commandContext func(ctx context.Context, name string, arg ...string) *exec.Cmd
|
||||
}
|
||||
|
||||
// New creates a new pg_dump adapter.
|
||||
func New() pgdump.Dumper {
|
||||
return &adapter{
|
||||
commandContext: exec.CommandContext,
|
||||
}
|
||||
}
|
||||
|
||||
// Dump executes pg_dump and writes the output to sink.
|
||||
func (a *adapter) Dump(
|
||||
ctx context.Context,
|
||||
opts pgdump.Options,
|
||||
sink io.Writer,
|
||||
) (retErr error) {
|
||||
defer func() {
|
||||
if pipeWriter, ok := sink.(*io.PipeWriter); ok {
|
||||
if retErr != nil {
|
||||
_ = pipeWriter.CloseWithError(retErr)
|
||||
} else {
|
||||
_ = pipeWriter.Close()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
args := buildArgs(opts)
|
||||
|
||||
cmd := a.commandContext(ctx, "pg_dump", args...)
|
||||
|
||||
env := os.Environ()
|
||||
if opts.Password != "" {
|
||||
env = append(env, fmt.Sprintf("PGPASSWORD=%s", opts.Password))
|
||||
}
|
||||
if opts.Host != "" {
|
||||
env = append(env, fmt.Sprintf("PGHOST=%s", opts.Host))
|
||||
}
|
||||
if opts.Port != 0 {
|
||||
env = append(env, fmt.Sprintf("PGPORT=%d", opts.Port))
|
||||
}
|
||||
if opts.User != "" {
|
||||
env = append(env, fmt.Sprintf("PGUSER=%s", opts.User))
|
||||
}
|
||||
if opts.Database != "" {
|
||||
env = append(env, fmt.Sprintf("PGDATABASE=%s", opts.Database))
|
||||
}
|
||||
cmd.Env = env
|
||||
|
||||
var stderrBuilder strings.Builder
|
||||
cmd.Stderr = &stderrBuilder
|
||||
cmd.Stdout = sink
|
||||
|
||||
runErr := cmd.Run()
|
||||
stderr := strings.TrimSpace(stderrBuilder.String())
|
||||
|
||||
if runErr != nil {
|
||||
if exitErr, ok := runErr.(*exec.ExitError); ok {
|
||||
return fmt.Errorf("%w (exit %d): %s", pgdump.ErrPgDumpFailed(exitErr.ExitCode()), exitErr.ExitCode(), stderr)
|
||||
}
|
||||
return runErr
|
||||
}
|
||||
|
||||
if cmd.ProcessState.ExitCode() != 0 {
|
||||
return fmt.Errorf("%w (exit %d): %s", pgdump.ErrPgDumpFailed(cmd.ProcessState.ExitCode()), cmd.ProcessState.ExitCode(), stderr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildArgs(opts pgdump.Options) []string {
|
||||
excludeTables := opts.ExcludeTables
|
||||
if len(excludeTables) == 0 {
|
||||
excludeTables = make([]string, 1)
|
||||
excludeTables[0] = "e2e_one_time_keys_json"
|
||||
}
|
||||
|
||||
args := make([]string, 0, len(excludeTables)+1)
|
||||
args = append(args, "--format=custom")
|
||||
|
||||
for _, table := range excludeTables {
|
||||
args = append(args, "--exclude-table="+table)
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
Reference in New Issue
Block a user