|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + "log" |
| 7 | + "os" |
| 8 | + "syscall" |
| 9 | + |
| 10 | + "github.com/dgraph-io/badger/v4" |
| 11 | + "github.com/dgraph-io/badger/v4/options" |
| 12 | + "github.com/urfave/cli/v3" |
| 13 | + "golang.org/x/term" |
| 14 | +) |
| 15 | + |
| 16 | +func main() { |
| 17 | + app := &cli.Command{ |
| 18 | + Name: "print-keys", |
| 19 | + Usage: "Print all keys from a BadgerDB database", |
| 20 | + Flags: []cli.Flag{ |
| 21 | + &cli.StringFlag{ |
| 22 | + Name: "db-path", |
| 23 | + Aliases: []string{"p"}, |
| 24 | + Usage: "Path to the BadgerDB database directory", |
| 25 | + Required: true, |
| 26 | + }, |
| 27 | + }, |
| 28 | + Action: printKeys, |
| 29 | + } |
| 30 | + |
| 31 | + if err := app.Run(context.Background(), os.Args); err != nil { |
| 32 | + log.Fatal(err) |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +func printKeys(ctx context.Context, cmd *cli.Command) error { |
| 37 | + dbPath := cmd.String("db-path") |
| 38 | + |
| 39 | + // Prompt for password |
| 40 | + fmt.Print("Enter database password: ") |
| 41 | + passwordBytes, err := term.ReadPassword(int(syscall.Stdin)) |
| 42 | + if err != nil { |
| 43 | + return fmt.Errorf("failed to read password: %v", err) |
| 44 | + } |
| 45 | + fmt.Println() // Print newline after password input |
| 46 | + password := string(passwordBytes) |
| 47 | + |
| 48 | + // Configure BadgerDB options |
| 49 | + opts := badger.DefaultOptions(dbPath). |
| 50 | + WithCompression(options.ZSTD). |
| 51 | + WithEncryptionKey([]byte(password)). |
| 52 | + WithIndexCacheSize(16 << 20). |
| 53 | + WithBlockCacheSize(32 << 20). |
| 54 | + WithReadOnly(true) // Open in read-only mode for safety |
| 55 | + |
| 56 | + // Open the database |
| 57 | + db, err := badger.Open(opts) |
| 58 | + if err != nil { |
| 59 | + return fmt.Errorf("failed to open BadgerDB: %v", err) |
| 60 | + } |
| 61 | + defer db.Close() |
| 62 | + |
| 63 | + fmt.Printf("Opening database at: %s\n", dbPath) |
| 64 | + fmt.Println("=== All Keys in Database ===") |
| 65 | + |
| 66 | + // Iterate through all keys |
| 67 | + err = db.View(func(txn *badger.Txn) error { |
| 68 | + opts := badger.DefaultIteratorOptions |
| 69 | + opts.PrefetchValues = false // We only need keys, not values |
| 70 | + it := txn.NewIterator(opts) |
| 71 | + defer it.Close() |
| 72 | + |
| 73 | + count := 0 |
| 74 | + for it.Rewind(); it.Valid(); it.Next() { |
| 75 | + item := it.Item() |
| 76 | + key := string(item.Key()) |
| 77 | + count++ |
| 78 | + fmt.Printf("%d. %s\n", count, key) |
| 79 | + } |
| 80 | + |
| 81 | + if count == 0 { |
| 82 | + fmt.Println("No keys found in the database.") |
| 83 | + } else { |
| 84 | + fmt.Printf("\nTotal keys: %d\n", count) |
| 85 | + } |
| 86 | + |
| 87 | + return nil |
| 88 | + }) |
| 89 | + |
| 90 | + if err != nil { |
| 91 | + return fmt.Errorf("failed to iterate over database: %v", err) |
| 92 | + } |
| 93 | + |
| 94 | + return nil |
| 95 | +} |
0 commit comments