diff --git a/script.go b/script.go index 9c7dfae..e9e8fdb 100644 --- a/script.go +++ b/script.go @@ -38,6 +38,7 @@ func ScriptCommands(db *DB) hive.ScriptCmdsOut { "db/lowerbound": LowerBoundCmd(db), "db/watch": WatchCmd(db), "db/initialized": InitializedCmd(db), + "db/dump": DumpCmd(db), }) } @@ -60,7 +61,7 @@ func DBCmd(db *DB) script.Cmd { "", "The individual tables can be manipulated and inspected with the", "other commands. See 'help -v db/show' etc. for detailed help.", - "Here is some examples to get you statred:", + "Here is some examples to get you started:", "", "> db/show example", "Name X", @@ -93,6 +94,46 @@ func DBCmd(db *DB) script.Cmd { ) } +func DumpCmd(db *DB) script.Cmd { + return script.Command( + script.CmdUsage{ + Summary: "Dump StateDB contents as JSON", + Flags: func(fs *pflag.FlagSet) { + fs.StringP("out", "o", "", "File to write to instead of stdout") + }, + Detail: []string{ + "The contents are written to stdout, but can be written to", + "a file instead with the -o flag.", + }, + }, + func(s *script.State, args ...string) (script.WaitFunc, error) { + file, err := s.Flags.GetString("out") + if err != nil { + return nil, err + } + + return func(s *script.State) (stdout string, stderr string, err error) { + var ( + buf strings.Builder + w io.Writer = &buf + ) + + if file != "" { + f, err := os.OpenFile(s.Path(file), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) + if err != nil { + return "", "", fmt.Errorf("OpenFile(%s): %w", file, err) + } + defer f.Close() + w = f + } + + err = db.ReadTxn().WriteJSON(w) + return buf.String(), "", err + }, nil + }, + ) +} + func InitializedCmd(db *DB) script.Cmd { return script.Command( script.CmdUsage{ diff --git a/testdata/db.txtar b/testdata/db.txtar index 68ab7fe..9d78835 100644 --- a/testdata/db.txtar +++ b/testdata/db.txtar @@ -172,6 +172,13 @@ db/cmp test1 objs.table db/lowerbound --index=id --delete test1 2 db/cmp test1 obj1.table +# Retrieve a full DB dump +db/dump +cmp stdout dump-expected.json + +db/dump -o dump-actual.json +cmp dump-actual.json dump-expected.json + # Tables db @@ -236,3 +243,12 @@ ID Key Prefix Tags 2 10.1.2.3/32 baz, foo -- empty.table -- ID Key Prefix Tags +-- dump-expected.json -- +{ + "test1": [ + {"ID":1,"Tags":["bar","foo"]} + ], + "test2": [ + {"ID":2,"Tags":["baz","foo"]} + ] +}