• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

foomo / posh-providers / 14357203152

09 Apr 2025 12:31PM UTC coverage: 0.0%. Remained the same
14357203152

push

github

web-flow
Merge pull request #201 from foomo/feature/task-extension

feature/task-extension

0 of 109 new or added lines in 4 files covered. (0.0%)

1 existing line in 1 file now uncovered.

0 of 9014 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/postgres/command.go
1
package postgres
2

3
import (
4
        "context"
5
        "fmt"
6
        "os"
7
        "time"
8

9
        "github.com/foomo/posh-providers/arbitrary/zip"
10
        "github.com/foomo/posh/pkg/command/tree"
11
        "github.com/foomo/posh/pkg/log"
12
        "github.com/foomo/posh/pkg/prompt/goprompt"
13
        "github.com/foomo/posh/pkg/readline"
14
        "github.com/foomo/posh/pkg/shell"
15
        "github.com/pkg/errors"
16
)
17

18
type (
19
        Command struct {
20
                l           log.Logger
21
                zip         *zip.Zip
22
                commandTree tree.Root
23
        }
24
        CommandOption func(*Command)
25
)
26

27
// ------------------------------------------------------------------------------------------------
28
// ~ Options
29
// ------------------------------------------------------------------------------------------------
30

31
func CommandWithZip(v *zip.Zip) CommandOption {
×
32
        return func(o *Command) {
×
33
                o.zip = v
×
34
        }
×
35
}
36

37
// ------------------------------------------------------------------------------------------------
38
// ~ Constructor
39
// ------------------------------------------------------------------------------------------------
40

41
func NewCommand(l log.Logger, opts ...CommandOption) *Command {
×
42
        inst := &Command{
×
43
                l: l.Named("postgres"),
×
44
        }
×
45

×
46
        for _, opt := range opts {
×
47
                if opt != nil {
×
48
                        opt(inst)
×
49
                }
×
50
        }
51

52
        connectionFlags := func(fs *readline.FlagSets) {
×
53
                fs.Default().String("port", "", "database server port number")
×
54
                fs.Default().String("host", "", "database server host or socket directory")
×
NEW
55
                fs.Default().String("dbname", "", "connect to database name")
×
56
                fs.Default().String("username", "", "connect as specified database user")
×
57
        }
×
58

59
        inst.commandTree = tree.New(&tree.Node{
×
60
                Name:        "postgres",
×
61
                Description: "Postgres utilities",
×
62
                Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
×
63
                        connectionFlags(fs)
×
64
                        return nil
×
65
                },
×
66
                Execute: inst.execute,
67
                Nodes: tree.Nodes{
68
                        {
69
                                Name:        "dump",
70
                                Description: "Create a database dump",
71
                                Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
×
72
                                        fs.Default().Bool("verbose", false, "verbose mode")
×
73
                                        // Options controlling the output content:
×
74
                                        fs.Default().Bool("data-only", false, "dump only the data, not the schema")
×
75
                                        fs.Default().Bool("schema-only", false, "dump only the schema, no data")
×
76
                                        fs.Default().Bool("no-owner", false, "skip restoration of object ownership")
×
77
                                        fs.Default().String("format", "", "output file format ")
×
78
                                        // connection
×
79
                                        connectionFlags(fs)
×
80
                                        fs.Internal().Bool("zip", false, "create a zip file")
×
81
                                        fs.Internal().Bool("dump", false, "use dump format")
×
82
                                        fs.Internal().String("zip-cred", "", "configured zip credential name")
×
83
                                        if err := fs.Internal().SetValues("zip-cred", inst.zip.Config().CredentialNames()...); err != nil {
×
84
                                                return err
×
85
                                        }
×
86
                                        return nil
×
87
                                },
88
                                Args: tree.Args{
89
                                        {
90
                                                Name:        "database",
91
                                                Description: "Database name to dump",
92
                                        },
93
                                        {
94
                                                Name:        "dirname",
95
                                                Description: "Path to the dump file",
96
                                        },
97
                                },
98
                                Execute: inst.dump,
99
                        },
100
                        {
101
                                Name:        "run-cmd",
102
                                Description: "Run only single command",
103
                                Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
×
104
                                        connectionFlags(fs)
×
105
                                        return nil
×
106
                                },
×
107
                                Args: tree.Args{
108
                                        {
109
                                                Name: "command",
110
                                        },
111
                                },
112
                                Execute: inst.runCommand,
113
                        },
114
                        {
115
                                Name:        "run-file",
116
                                Description: "Execute commands from file",
117
                                Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
×
118
                                        connectionFlags(fs)
×
119
                                        return nil
×
120
                                },
×
121
                                Args: tree.Args{
122
                                        {
123
                                                Name: "filename",
124
                                        },
125
                                },
126
                                Execute: inst.runFile,
127
                        },
128
                        {
129
                                Name:        "restore",
130
                                Description: "Restore a database dump",
131
                                Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
×
132
                                        fs.Default().Bool("verbose", false, "verbose mode")
×
133
                                        // Options controlling the output content:
×
134
                                        fs.Default().Bool("data-only", false, "restore only the data, no schema")
×
135
                                        fs.Default().Bool("clean", false, "clean (drop) database objects before recreating")
×
NEW
136
                                        fs.Default().Bool("create", false, "create the target database")
×
137
                                        fs.Default().Bool("exit-on-error", false, "exit on error, default is to continue")
×
138
                                        fs.Default().Bool("schema-only", false, "restore only the schema, no data")
×
139
                                        fs.Default().Bool("no-owner", false, "skip restoration of object ownership")
×
140
                                        connectionFlags(fs)
×
141
                                        fs.Internal().String("zip-cred", "", "configured zip credential name")
×
142
                                        if err := fs.Internal().SetValues("zip-cred", inst.zip.Config().CredentialNames()...); err != nil {
×
143
                                                return err
×
144
                                        }
×
145
                                        return nil
×
146
                                },
147
                                Args: tree.Args{
148
                                        {
149
                                                Name:        "filename",
150
                                                Description: "Path to the dump file",
151
                                        },
152
                                },
153
                                Execute: inst.restore,
154
                        },
155
                },
156
        })
157

158
        return inst
×
159
}
160

161
// ------------------------------------------------------------------------------------------------
162
// ~ Public methods
163
// ------------------------------------------------------------------------------------------------
164

165
func (c *Command) Name() string {
×
166
        return c.commandTree.Node().Name
×
167
}
×
168

169
func (c *Command) Description() string {
×
170
        return c.commandTree.Node().Description
×
171
}
×
172

173
func (c *Command) Complete(ctx context.Context, r *readline.Readline) []goprompt.Suggest {
×
174
        return c.commandTree.Complete(ctx, r)
×
175
}
×
176

177
func (c *Command) Execute(ctx context.Context, r *readline.Readline) error {
×
178
        return c.commandTree.Execute(ctx, r)
×
179
}
×
180

181
func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
×
182
        return c.commandTree.Help(ctx, r)
×
183
}
×
184

185
// ------------------------------------------------------------------------------------------------
186
// ~ Private methods
187
// ------------------------------------------------------------------------------------------------
188

189
func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
×
190
        return shell.New(ctx, c.l, "psql").
×
191
                Args(r.Args()...).
×
192
                Args(r.Flags()...).
×
193
                Args(r.AdditionalArgs()...).
×
194
                Run()
×
195
}
×
196

197
func (c *Command) runFile(ctx context.Context, r *readline.Readline) error {
×
198
        return shell.New(ctx, c.l, "psql").
×
199
                Args(r.Flags()...).
×
200
                Args("--file", r.Args().At(1)).
×
201
                Args(r.AdditionalArgs()...).
×
202
                Run()
×
203
}
×
204

205
func (c *Command) runCommand(ctx context.Context, r *readline.Readline) error {
×
206
        return shell.New(ctx, c.l, "psql").
×
207
                Args(r.Flags()...).
×
208
                Args("--command", r.Args().At(1)).
×
209
                Args(r.AdditionalArgs()...).
×
210
                Run()
×
211
}
×
212

213
func (c *Command) dump(ctx context.Context, r *readline.Readline) error {
×
214
        fs := r.FlagSets().Default()
×
215
        ifs := r.FlagSets().Internal()
×
216

×
217
        database := r.Args().At(1)
×
218
        dirname := r.Args().At(2)
×
219
        if err := os.MkdirAll(dirname, 0700); err != nil {
×
220
                return err
×
221
        }
×
222

223
        filename := fmt.Sprintf("%s/%s-%s", dirname, database, time.Now().Format("20060102150405"))
×
224
        if log.MustGet(ifs.GetBool("dump"))(c.l) {
×
225
                filename += ".dump"
×
226
                if err := fs.Set("format", "custom"); err != nil {
×
227
                        return err
×
228
                }
×
229
        } else {
×
230
                filename += ".sql"
×
231
        }
×
232

NEW
233
        c.l.Info("Creating database dump: " + filename)
×
234
        if out, err := shell.New(ctx, c.l, "pg_dump").
×
235
                Args(fs.Visited().Args()...).
×
236
                Args(r.AdditionalFlags()...).
×
237
                Args(database).
×
238
                Args(r.AdditionalArgs()...).
×
239
                Args(">", filename).
×
240
                Output(); err != nil {
×
241
                return errors.Wrap(err, string(out))
×
242
        }
×
243

244
        if log.MustGet(ifs.GetBool("zip"))(c.l) {
×
NEW
245
                c.l.Info("Compressing database dump...")
×
246
                if err := c.zip.Create(ctx, filename); err != nil {
×
247
                        return err
×
248
                }
×
249
        }
250

251
        if cred := log.MustGet(ifs.GetString("zip-cred"))(c.l); cred != "" {
×
NEW
252
                c.l.Info("Securing database dump...")
×
253
                if err := c.zip.CreateWithPassword(ctx, filename, cred); err != nil {
×
254
                        return err
×
255
                }
×
256
        }
257

258
        return nil
×
259
}
260

261
func (c *Command) restore(ctx context.Context, r *readline.Readline) error {
×
262
        flags := r.Flags()
×
263
        filename := r.Args().At(1)
×
264

×
NEW
265
        c.l.Info("Restoring database dump: " + filename)
×
266
        if out, err := shell.New(ctx, c.l, "pg_restore").
×
267
                Args(flags...).
×
268
                Args(r.AdditionalFlags()...).
×
269
                Args(r.AdditionalArgs()...).
×
270
                Args(filename).
×
271
                Output(); err != nil {
×
272
                return errors.Wrap(err, string(out))
×
273
        }
×
274

275
        return nil
×
276
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc