-
Notifications
You must be signed in to change notification settings - Fork 671
Fix CLI tool print entire freelist. Add option to dump leaf element keys/value bytes. #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
9d9f819
to
fefb4a0
Compare
Codecov Report
@@ Coverage Diff @@
## master #50 +/- ##
=========================================
Coverage ? 85.52%
=========================================
Files ? 9
Lines ? 1851
Branches ? 0
=========================================
Hits ? 1583
Misses ? 159
Partials ? 109 Continue to review full report at Codecov.
|
I don't think there should be dependencies in bbolt aside from the standard libraries since it was deliberately avoided in boltdb. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
functionality looks like a candidate for a new command
also probably a good time to update .gitignore with cmd/bolt/bolt...
db_test.go
Outdated
@@ -450,7 +450,7 @@ func TestDB_Open_ReadOnly(t *testing.T) { | |||
// Read from a read-only transaction. | |||
if err := readOnlyDB.View(func(tx *bolt.Tx) error { | |||
value := tx.Bucket([]byte("widgets")).Get([]byte("foo")) | |||
if bytes.Compare(value, []byte("bar")) != 0 { | |||
if !bytes.Equal(value, []byte("bar")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already picked this up in e39821f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, I'll rebase.
cmd/bolt/main.go
Outdated
if p.count == 0xFFFF { | ||
idx = 1 | ||
count = int(((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[0]) | ||
fmt.Fprintf(w, "Item Count of 65535 (max uint16) indicates a freelist overflow. Actual Item Count: %d\n", count) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sort of wordy/obscure, maybe only have Item Count:
but determine the count depending on whether it's overflow or not? if the physical dump of the page structure is needed it should probably be handled separate from this
@@ -653,7 +714,14 @@ func (cmd *PageCommand) PrintPage(w io.Writer, r io.ReaderAt, pageID int, pageSi | |||
// Usage returns the help message. | |||
func (cmd *PageCommand) Usage() string { | |||
return strings.TrimLeft(` | |||
usage: bolt page -page PATH pageid [pageid...] | |||
usage: bolt page PATH pageid [pageid...] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DumpCommand
's Usage looks similarly broken, might as well fix that too...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure enough. Fixed.
cmd/bolt/main.go
Outdated
p := (*page)(unsafe.Pointer(&pageBytes[0])) | ||
|
||
if index >= p.count { | ||
return nil, fmt.Errorf("Expected item index >= 0 and < %d, but got %d.", p.count, index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fmt.Errorf("leafPageElement: expected item index less than %d, got %d", p.count, index)
to closer match the other expected
errors and since index and p.count are unsigned
cmd/bolt/main.go
Outdated
fmt.Fprintf(cmd.Stdout, "Page ID: %d\n", p.id) | ||
fmt.Fprintf(cmd.Stdout, "Page Type: %s\n", p.Type()) | ||
fmt.Fprintf(cmd.Stdout, "Total Size: %d bytes\n", len(buf)) | ||
if options.itemKey == -1 && options.itemValue == -1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
judging by the special-casing and that pages
is described as print one or more pages in human readable format
, this might be better as a separate command dump-item [-key|-value] PATH pageid idx
instead of overloading the pages command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Humm, yeah. I had been thinking about splitting this out. I'll do it now.
it seems like the bin file is also checked in. remove it? |
Oops, I'll remove the bin file and check the .gitignore settings. |
8f03d2b
to
e4081c7
Compare
cmd/bolt/main.go
Outdated
return cmd.PrintLeafItemKey(cmd.Stdout, buf, uint16(itemID)) | ||
case options.value: | ||
return cmd.PrintLeafItemValue(cmd.Stdout, buf, uint16(itemID)) | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this to line 465, close to other validation?
cmd/bolt/main.go
Outdated
return ErrUsage | ||
} | ||
|
||
if options.key && options.value { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not allow both to be set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds reasonable. Maybe we should do something more like etcd where by default we print key and value, and provide for --key-only
and --value-only
flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right. i hope user can use the command without specifying any flag by default. right now they have to say --key or --value. If no option is provided, it will fail. not a good UX in my opinion.
The feature looks good in general. Let us clean up the issues mentioned in the review and get this merged. Thank you! |
e4081c7
to
ccbe64a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm aside from the newline bit
return err | ||
} | ||
|
||
if !options.valueOnly { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if !options.valuesOnly { ... }
if !options.keyOnly { ... }
so the output with no flags exactly matches the physical layout since this is a raw dump.
etcdctl's default output mode inserts a newline and in retrospect I think it makes the output really difficult / impossible to parse, but it's too late now. printf("%q\n%q\n",key,val)
seems like the best/easiest human-readable way to print binary data, if that's worth pursuing in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we do something like this:
bolt page-item <dbfile> <pageid> <itemid>
"<%q encoded key>"
"<%q encoded value>"
bolt page-item --raw-key-only <dbfile> <pageid> <itemid>
<key bytes>
bolt page-item --raw-value-only <dbfile> <pageid> <itemid>
<value bytes>
?
This solves a couple problems:
- It provides a default output that won't mess up someones terminal by outputting raw bytes, and that prints out the key and value, which, if ASCII, will be rendered nicely.
- It avoid use of "\n" as a delimiter between binary output.
- If one needs the raw bytes, they have convenient flags they can use to get the key and value individually.
ccbe64a
to
6c39a12
Compare
Based on conversation, I've moved things around a bit. Renamed the new subcommand to The default for To get to raw keys and values, switched to |
6c39a12
to
b02f9a7
Compare
cmd/bolt/main.go
Outdated
// Parse flags. | ||
options := &pageItemOptions{} | ||
fs := flag.NewFlagSet("", flag.ContinueOnError) | ||
fs.BoolVar(&options.keyOnly, "raw-key-only", false, "Directly output the key as raw, unencoded, bytes.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
raw or encoded should be another option. i do not like the idea to fix format and output content together.
@jpbetz what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's better, much more compose-able, and we still get our safe, easy to parse defaults. Fixing.
… of leaf elements.
b02f9a7
to
69918b9
Compare
lgtm |
This includes two small fixes to the bolt CLI that we've needed a couple times in the past--
bolt page
to print an accurate freelist. Won't be relevant for dbs that don't persist the freelist, but still an improvement to have the command print the most accurate information available.bolt page-item
to print a page item key and value. Had been handy for digging into data values at the bbolt level.