Adding support for data types

This commit is contained in:
Brian Buller 2019-10-23 16:14:18 -05:00
parent 2970b1c912
commit 4ab1f201c5
6 changed files with 122 additions and 21 deletions

View File

@ -32,9 +32,10 @@ type BoltBucket struct {
BoltPair is just a struct representation of a Pair in the Bolt DB
*/
type BoltPair struct {
parent *BoltBucket
key string
val string
parent *BoltBucket
key string
val string
dataType *Datatype
}
func (bd *BoltDB) getGenericFromPath(path []string) (*BoltBucket, *BoltPair, error) {

9
datatype.go Normal file
View File

@ -0,0 +1,9 @@
package main
// A Datatype interface knows how to convert a byte slice into a
// specific data type.
type Datatype interface {
Name() string // Type Name, for UI display
ToString([]byte) (string, error) // ToString takes a []byte from the DB and returns the string to display
FromString(string) ([]byte, error) // FromString takes a string and returns the []byte for the DB
}

37
datatype_int.go Normal file
View File

@ -0,0 +1,37 @@
package main
import (
"encoding/binary"
"errors"
"strconv"
)
// Datatype_Uint64 manages the uint64 data type
// All conversions just use the binary package
type Datatype_Uint64 struct{}
func (t *Datatype_Uint64) Name() string {
return "uint64"
}
func (t *Datatype_Uint64) ToString(data []byte) (string, error) {
ret, bt := binary.Uvarint(data)
if bt == 0 {
return "", errors.New("Byte Buffer too small")
} else if bt < 0 {
return "", errors.New("Value larger than 64 bits")
}
return strconv.FormatUint(ret, 10), nil
}
func (t *Datatype_Uint64) FromString(val string) ([]byte, error) {
var err error
var u uint64
buf := make([]byte, binary.MaxVarintLen64)
u, err = strconv.ParseUint(val, 10, 64)
if err != nil {
return nil, err
}
binary.PutUvarint(buf, u)
return buf, nil
}

37
datatype_string.go Normal file
View File

@ -0,0 +1,37 @@
package main
import (
"errors"
"unicode/utf8"
)
// Datatype_String is basically the default type for
// boltbrowser (and the boltease library)
type Datatype_String struct{}
func (t *Datatype_String) Name() string {
return "string"
}
func (t *Datatype_String) ToString(data []byte) (string, error) {
if utf8.Valid(data) {
ok := true
for _, r := range string(data) {
if r < 0x20 {
ok = false
break
} else if r >= 0x7f && r <= 0x9f {
ok = false
break
}
}
if ok {
return string(data), nil
}
}
return "", errors.New("Invalid String Data")
}
func (t *Datatype_String) FromString(val string) ([]byte, error) {
return []byte(val), nil
}

13
main.go
View File

@ -18,6 +18,8 @@ var databaseFiles []string
var db *bolt.DB
var memBolt *BoltDB
var datatypes map[string]Datatype
var currentFilename string
const DefaultDBOpenTimeout = time.Second
@ -95,6 +97,7 @@ func main() {
var err error
parseArgs()
initDataTypes()
err = termbox.Init()
if err != nil {
@ -134,3 +137,13 @@ func main() {
defer db.Close()
}
}
func initDataTypes() {
datatypes = make(map[string]Datatype)
for _, t := range []Datatype{
&Datatype_String{},
&Datatype_Uint64{},
} {
datatypes[t.Name()] = t
}
}

View File

@ -204,6 +204,10 @@ func (screen *BrowserScreen) handleBrowseKeyEvent(event termbox.Event) int {
} else if event.Ch == 'X' {
// Export Key/Value (or Bucket) as JSON
screen.startExportJSON()
} else if event.Ch == 't' {
// TODO: change the type of the pair value being viewed
}
return BrowserScreenIndex
}
@ -544,13 +548,13 @@ func (screen *BrowserScreen) buildLeftPane(style Style) {
for i := range screen.db.buckets {
screen.leftPaneBuffer = append(screen.leftPaneBuffer, screen.bucketToLines(&screen.db.buckets[i], style)...)
}
// Find the cursor in the leftPane
for k, v := range screen.leftPaneBuffer {
if v.Fg == style.cursorFg {
screen.leftViewPort.scrollRow = k
break
}
}
// Find the cursor in the leftPane
for k, v := range screen.leftPaneBuffer {
if v.Fg == style.cursorFg {
screen.leftViewPort.scrollRow = k
break
}
}
}
func (screen *BrowserScreen) drawLeftPane(style Style) {
@ -562,19 +566,19 @@ func (screen *BrowserScreen) drawLeftPane(style Style) {
screen.leftViewPort.bytesPerRow = w
screen.leftViewPort.numberOfRows = h - 2
termboxUtil.FillWithChar('=', 0, 1, w, 1, style.defaultFg, style.defaultBg)
startX, startY := 0, 3
startX, startY := 0, 3
screen.leftViewPort.firstRow = startY
treeOffset := 0
maxCursor := screen.leftViewPort.numberOfRows * 2 / 3
treeOffset := 0
maxCursor := screen.leftViewPort.numberOfRows * 2 / 3
if screen.leftViewPort.scrollRow > maxCursor {
treeOffset = screen.leftViewPort.scrollRow - maxCursor
}
if len(screen.leftPaneBuffer) > 0 {
for k, v := range screen.leftPaneBuffer[treeOffset:] {
termboxUtil.DrawStringAtPoint(v.Text, startX, (startY + k - 1), v.Fg, v.Bg)
}
}
if screen.leftViewPort.scrollRow > maxCursor {
treeOffset = screen.leftViewPort.scrollRow - maxCursor
}
if len(screen.leftPaneBuffer) > 0 {
for k, v := range screen.leftPaneBuffer[treeOffset:] {
termboxUtil.DrawStringAtPoint(v.Text, startX, (startY + k - 1), v.Fg, v.Bg)
}
}
}
func (screen *BrowserScreen) buildRightPane(style Style) {