Restrict generations command to single db

This commit is contained in:
Ben Johnson
2020-12-30 15:44:21 -07:00
parent ffc25e2654
commit 8a7d8175fc

View File

@@ -12,53 +12,46 @@ import (
"time" "time"
) )
type GenerationsCommand struct { type GenerationsCommand struct{}
ConfigPath string
Config Config
DBPath string
}
func NewGenerationsCommand() *GenerationsCommand { func NewGenerationsCommand() *GenerationsCommand {
return &GenerationsCommand{} return &GenerationsCommand{}
} }
func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error) { func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error) {
var configPath string
fs := flag.NewFlagSet("litestream-generations", flag.ContinueOnError) fs := flag.NewFlagSet("litestream-generations", flag.ContinueOnError)
registerConfigFlag(fs, &c.ConfigPath) registerConfigFlag(fs, &configPath)
replicaName := fs.String("replica", "", "replica name")
fs.Usage = c.Usage fs.Usage = c.Usage
if err := fs.Parse(args); err != nil { if err := fs.Parse(args); err != nil {
return err return err
} else if fs.NArg() == 0 || fs.Arg(0) == "" {
return fmt.Errorf("database path required")
} else if fs.NArg() > 1 { } else if fs.NArg() > 1 {
return fmt.Errorf("too many arguments") return fmt.Errorf("too many arguments")
} }
// Load configuration. // Load configuration.
if c.ConfigPath == "" { if configPath == "" {
return errors.New("-config required") return errors.New("-config required")
} }
config, err := ReadConfigFile(c.ConfigPath) config, err := ReadConfigFile(configPath)
if err != nil { if err != nil {
return err return err
} }
// Determine absolute path for database, if specified. // Determine absolute path for database.
if c.DBPath = fs.Arg(0); c.DBPath != "" { dbPath, err := filepath.Abs(fs.Arg(0))
if c.DBPath, err = filepath.Abs(c.DBPath); err != nil { if err != nil {
return err return err
} }
}
// List each generation.
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
fmt.Fprintln(w, "db\tname\tgeneration\tlag\tstart\tend")
for _, dbConfig := range config.DBs {
// Filter database, if specified in the arguments.
if c.DBPath != "" && dbConfig.Path != c.DBPath {
continue
}
// Instantiate DB from from configuration. // Instantiate DB from from configuration.
dbConfig := config.DBConfig(dbPath)
if dbConfig == nil {
return fmt.Errorf("database not found in config: %s", dbPath)
}
db, err := newDBFromConfig(dbConfig) db, err := newDBFromConfig(dbConfig)
if err != nil { if err != nil {
return err return err
@@ -70,8 +63,14 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
return err return err
} }
// Iterate over each replica in the database. // List each generation.
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
fmt.Fprintln(w, "name\tgeneration\tlag\tstart\tend")
for _, r := range db.Replicas { for _, r := range db.Replicas {
if *replicaName != "" && r.Name() != *replicaName {
continue
}
generations, err := r.Generations(ctx) generations, err := r.Generations(ctx)
if err != nil { if err != nil {
log.Printf("%s: cannot list generations: %s", r.Name(), err) log.Printf("%s: cannot list generations: %s", r.Name(), err)
@@ -86,8 +85,7 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
continue continue
} }
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
db.Path(),
r.Name(), r.Name(),
generation, generation,
truncateDuration(stats.UpdatedAt.Sub(updatedAt)).String(), truncateDuration(stats.UpdatedAt.Sub(updatedAt)).String(),
@@ -96,7 +94,6 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
) )
} }
} }
}
w.Flush() w.Flush()
return nil return nil
@@ -104,7 +101,7 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
func (c *GenerationsCommand) Usage() { func (c *GenerationsCommand) Usage() {
fmt.Printf(` fmt.Printf(`
The generations command lists all generations across all replicas along with The generations command lists all generations for a database. It also lists
stats about their lag behind the primary database and the time range they cover. stats about their lag behind the primary database and the time range they cover.
Usage: Usage:
@@ -116,6 +113,9 @@ Arguments:
-config PATH -config PATH
Specifies the configuration file. Defaults to %s Specifies the configuration file. Defaults to %s
-replica NAME
Optional, filters by replica.
`[1:], `[1:],
DefaultConfigPath, DefaultConfigPath,
) )