Skip to content

Commit 279bbd6

Browse files
authored
Merge pull request #2 from piax93/bucket-selection-option
add option to select only certain buckets
2 parents f18abf7 + 0c47e2c commit 279bbd6

File tree

5 files changed

+115
-24
lines changed

5 files changed

+115
-24
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ $ go get -u github.com/konoui/boltdb-exporter
88

99
## Usage
1010
```
11-
$ boltdb-exporter --db <database filename> --format yaml
11+
$ boltdb-exporter --db <database filename> --format yaml [--bucket <root bucket name> ...]
1212
```
1313

1414
## Example

main.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,22 @@ import (
1212
"github.com/peterbourgon/ff/v3/ffcli"
1313
)
1414

15+
type arrayFlag []string
16+
1517
type config struct {
16-
filename string
17-
outputFormat string
18-
marshaler func(interface{}) ([]byte, error)
18+
filename string
19+
outputFormat string
20+
bucketSelection arrayFlag
21+
marshaler func(interface{}) ([]byte, error)
22+
}
23+
24+
func (i *arrayFlag) Set(value string) error {
25+
*i = append(*i, value)
26+
return nil
27+
}
28+
29+
func (i *arrayFlag) String() string {
30+
return "..."
1931
}
2032

2133
func newRootCmd() *ffcli.Command {
@@ -37,6 +49,7 @@ func newRootCmd() *ffcli.Command {
3749
func (cfg *config) registerFlags(fs *flag.FlagSet) {
3850
fs.StringVar(&cfg.outputFormat, "format", "json", "support json/yaml")
3951
fs.StringVar(&cfg.filename, "db", "", "database filename")
52+
fs.Var(&cfg.bucketSelection, "bucket", "select root-level bucket to export (can be used multiple times)")
4053
}
4154

4255
func (cfg *config) validate() error {
@@ -66,7 +79,15 @@ func (cfg *config) run() error {
6679
return err
6780
}
6881

69-
b, err := exporter.Export(cfg.filename, cfg.marshaler)
82+
var bucketSelectionSet map[string]bool
83+
if len(cfg.bucketSelection) > 0 {
84+
bucketSelectionSet = make(map[string]bool)
85+
for _, bucket := range cfg.bucketSelection {
86+
bucketSelectionSet[bucket] = true
87+
}
88+
}
89+
90+
b, err := exporter.Export(cfg.filename, cfg.marshaler, bucketSelectionSet)
7091
if err != nil {
7192
return err
7293
}

pkg/exporter/export.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ import (
66
"github.com/boltdb/bolt"
77
)
88

9-
func Export(filename string, marshaler func(interface{}) ([]byte, error)) (ret []byte, err error) {
9+
func Export(filename string, marshaler func(interface{}) ([]byte, error), bucketSelection map[string]bool) (ret []byte, err error) {
1010
db, err := bolt.Open(filename, 0600, &bolt.Options{
1111
ReadOnly: true,
1212
})
1313
if err != nil {
1414
return nil, err
1515
}
1616
defer db.Close()
17-
return export(db, marshaler)
17+
return export(db, marshaler, bucketSelection)
1818
}
1919

20-
func export(db *bolt.DB, marshaler func(interface{}) ([]byte, error)) (ret []byte, err error) {
20+
func export(db *bolt.DB, marshaler func(interface{}) ([]byte, error), bucketSelection map[string]bool) (ret []byte, err error) {
2121
err = db.View(func(tx *bolt.Tx) error {
2222
c := tx.Cursor()
23-
rawMap := makeRawMap(tx, c)
23+
rawMap := makeRawMap(tx, c, bucketSelection)
2424
ret, err = marshaler(rawMap)
2525
if err != nil {
2626
return err
@@ -30,22 +30,29 @@ func export(db *bolt.DB, marshaler func(interface{}) ([]byte, error)) (ret []byt
3030
return
3131
}
3232

33-
func makeRawMap(tx *bolt.Tx, c *bolt.Cursor) map[string]interface{} {
33+
func makeRawMap(tx *bolt.Tx, c *bolt.Cursor, bucketSelection map[string]bool) map[string]interface{} {
3434
rawMap := make(map[string]interface{})
35-
recursiveRawMap(tx, c, rawMap)
35+
recursiveRawMap(tx, c, rawMap, bucketSelection)
3636
return rawMap
3737
}
3838

39-
func recursiveRawMap(tx *bolt.Tx, c *bolt.Cursor, rawMap map[string]interface{}) map[string]interface{} {
39+
func recursiveRawMap(tx *bolt.Tx, c *bolt.Cursor, rawMap map[string]interface{}, bucketSelection map[string]bool) map[string]interface{} {
4040
for k, v := c.First(); k != nil; k, v = c.Next() {
41+
// skip bucket if not selected
42+
if bucketSelection != nil {
43+
if _, ok := bucketSelection[string(k)]; !ok {
44+
continue
45+
}
46+
}
47+
4148
if v == nil {
4249
bucket := c.Bucket().Bucket(k)
4350
if bucket == nil {
4451
bucket = tx.Bucket(k)
4552
}
4653
nextCursor := bucket.Cursor()
4754
nextMap := make(map[string]interface{})
48-
rawMap[string(k)] = recursiveRawMap(tx, nextCursor, nextMap)
55+
rawMap[string(k)] = recursiveRawMap(tx, nextCursor, nextMap, nil)
4956
continue
5057
}
5158

pkg/exporter/export_test.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,29 @@ var testData = TestData{
4545

4646
func Test_export(t *testing.T) {
4747
tests := []struct {
48-
name string
49-
wantPath string
50-
setuper func(*testing.T, string) *bolt.DB
51-
update bool
48+
name string
49+
wantPath string
50+
setuper func(*testing.T, string) *bolt.DB
51+
update bool
52+
selection map[string]bool
5253
}{
5354
{
54-
name: "multi buckets",
55-
wantPath: filepath.Join("testdata", "single-output.json"),
56-
setuper: setupSingle,
55+
name: "multi buckets",
56+
wantPath: filepath.Join("testdata", "single-output.json"),
57+
setuper: setupSingle,
58+
selection: nil,
5759
},
5860
{
59-
name: "nested buckets",
60-
setuper: setupNested,
61-
wantPath: filepath.Join("testdata", "nested-output.json"),
61+
name: "nested buckets",
62+
setuper: setupNested,
63+
wantPath: filepath.Join("testdata", "nested-output.json"),
64+
selection: nil,
65+
},
66+
{
67+
name: "bucket selection",
68+
wantPath: filepath.Join("testdata", "single-output-selection.json"),
69+
setuper: setupSingle,
70+
selection: map[string]bool{"bucket2": true},
6271
},
6372
}
6473

@@ -67,7 +76,7 @@ func Test_export(t *testing.T) {
6776
db := tt.setuper(t, filename)
6877
defer cleanup(t, db, filename)
6978

70-
gotData, err := export(db, json.Marshal)
79+
gotData, err := export(db, json.Marshal, tt.selection)
7180
if err != nil {
7281
t.Error(err)
7382
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"bucket2": {
3+
"1": {
4+
"Data1": "1",
5+
"Data2": "2",
6+
"Data3": 3,
7+
"Data4": {
8+
"Data1": "4-1",
9+
"Data2": "4-2",
10+
"Data3": 3,
11+
"Data4": null,
12+
"Data5": null
13+
},
14+
"Data5": {
15+
"Data1": "data5-nested1",
16+
"Data2": "data5-nested2",
17+
"Data3": 0,
18+
"Data4": {
19+
"Data1": "5-4-1",
20+
"Data2": "5-4-2",
21+
"Data3": 541,
22+
"Data4": null,
23+
"Data5": null
24+
},
25+
"Data5": null
26+
}
27+
},
28+
"2": {
29+
"Data1": "1",
30+
"Data2": "2",
31+
"Data3": 3,
32+
"Data4": {
33+
"Data1": "4-1",
34+
"Data2": "4-2",
35+
"Data3": 3,
36+
"Data4": null,
37+
"Data5": null
38+
},
39+
"Data5": {
40+
"Data1": "data5-nested1",
41+
"Data2": "data5-nested2",
42+
"Data3": 0,
43+
"Data4": {
44+
"Data1": "5-4-1",
45+
"Data2": "5-4-2",
46+
"Data3": 541,
47+
"Data4": null,
48+
"Data5": null
49+
},
50+
"Data5": null
51+
}
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)