// Copyright 2022 Molecula Corp. (DBA FeatureBase). // SPDX-License-Identifier: Apache-2.0 package cmd import ( "errors" "fmt" "strconv" "github.com/featurebasedb/featurebase/v3/ctl" "github.com/featurebasedb/featurebase/v3/logger" "github.com/spf13/cobra" ) func newRBFCommand(logdest logger.Logger) *cobra.Command { cmd := &cobra.Command{ Use: "rbf", Short: "Inspect RBF data files.", Long: ` Provides a set of commands for inspecting RBF data files. `, } cmd.AddCommand(newRBFCheckCommand(logdest)) cmd.AddCommand(newRBFDumpCommand(logdest)) cmd.AddCommand(newRBFPagesCommand(logdest)) cmd.AddCommand(newRBFPageCommand(logdest)) return cmd } func newRBFCheckCommand(logdest logger.Logger) *cobra.Command { c := ctl.NewRBFCheckCommand(logdest) cmd := &cobra.Command{ Use: "check [flags] PATH", Short: "Run consistency check on RBF data.", Long: ` Executes a consistency check on an RBF data directory. `, Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return fmt.Errorf("data directory path required") } else if len(args) > 1 { return fmt.Errorf("too many command line arguments") } c.Path = args[0] return nil }, RunE: UsageErrorWrapper(c), } return cmd } func newRBFDumpCommand(logdest logger.Logger) *cobra.Command { c := ctl.NewRBFDumpCommand(logdest) cmd := &cobra.Command{ Use: "dump [flags] PATH PGNO [PGNO...]", Short: "Prints RBF raw page data", Long: ` Dumps the raw hex data for one or more RBF pages. `, Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return fmt.Errorf("data directory path required") } else if len(args) == 1 { return fmt.Errorf("page number required") } c.Path = args[0] for _, arg := range args[1:] { pgno, err := strconv.Atoi(arg) if err != nil { return errors.New("invalid page number") } c.Pgnos = append(c.Pgnos, uint32(pgno)) } return nil }, RunE: UsageErrorWrapper(c), } return cmd } func newRBFPagesCommand(logdest logger.Logger) *cobra.Command { c := ctl.NewRBFPagesCommand(logdest) cmd := &cobra.Command{ Use: "pages [flags] PATH", Short: "Prints metadata for the list of all pages", Long: ` Prints a line for every page in the database with its type/status. `, Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return fmt.Errorf("data directory path required") } else if len(args) > 1 { return fmt.Errorf("too many command line arguments") } c.Path = args[0] return nil }, RunE: UsageErrorWrapper(c), } flags := cmd.Flags() flags.BoolVar(&c.WithTree, "with-tree", false, "Display b-tree name for each row") return cmd } func newRBFPageCommand(logdest logger.Logger) *cobra.Command { c := ctl.NewRBFPageCommand(logdest) cmd := &cobra.Command{ Use: "page [flags] PATH PGNO [PGNO...]", Short: "Prints data for a page(s)", Long: ` Prints the header & cell data for one or more pages. `, Args: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return fmt.Errorf("data directory path required") } else if len(args) == 1 { return fmt.Errorf("page number required") } c.Path = args[0] for _, arg := range args[1:] { pgno, err := strconv.Atoi(arg) if err != nil { return errors.New("invalid page number") } c.Pgnos = append(c.Pgnos, uint32(pgno)) } return nil }, RunE: UsageErrorWrapper(c), } return cmd }