Things are progressing

Deleting and Editing are working
This commit is contained in:
Brian Buller 2015-05-04 13:50:41 -05:00
parent cc46445c69
commit 20338d4671
3 changed files with 191 additions and 58 deletions

View File

@ -60,6 +60,38 @@ func (bd *BoltDB) getGenericFromPath(path []string) (*BoltBucket, *BoltPair, err
return nil, nil, errors.New("Invalid Path")
}
func (bd *BoltDB) removeGenericAtPath(path []string) error {
b, p, err := bd.getGenericFromPath(path)
if err != nil {
return err
}
if p != nil {
pb := p.parent
for i := range pb.pairs {
if pb.pairs[i-1].key == p.key {
pb.pairs = append(pb.pairs[:i-1], pb.pairs[i+1:]...)
}
}
}
if b != nil {
pb := b.parent
if pb == nil {
for i := range bd.buckets {
if bd.buckets[i-1].name == b.name {
bd.buckets = append(bd.buckets[:i-1], bd.buckets[i+1:]...)
}
}
} else {
for i := range pb.buckets {
if pb.buckets[i-1].name == b.name {
pb.buckets = append(pb.buckets[:i-1], pb.buckets[i+1:]...)
}
}
}
}
return err
}
func (bd *BoltDB) getBucketFromPath(path []string) (*BoltBucket, error) {
if len(path) > 0 {
// Find the BoltBucket with a path == path
@ -193,6 +225,33 @@ func (bd *BoltDB) getNextVisiblePath(path []string) []string {
return nil
}
func (bd *BoltDB) toggleOpenBucket(path []string) error {
// Find the BoltBucket with a path == path
b, err := bd.getBucketFromPath(path)
if err == nil {
b.expanded = !b.expanded
}
return err
}
func (bd *BoltDB) closeBucket(path []string) error {
// Find the BoltBucket with a path == path
b, err := bd.getBucketFromPath(path)
if err == nil {
b.expanded = false
}
return err
}
func (bd *BoltDB) openBucket(path []string) error {
// Find the BoltBucket with a path == path
b, err := bd.getBucketFromPath(path)
if err == nil {
b.expanded = true
}
return err
}
func (bd *BoltDB) getBucket(k string) (*BoltBucket, error) {
for i := range bd.buckets {
if bd.buckets[i].name == k {
@ -202,6 +261,29 @@ func (bd *BoltDB) getBucket(k string) (*BoltBucket, error) {
return nil, errors.New("Bucket Not Found")
}
func (bd *BoltDB) syncOpenBuckets(shadow *BoltDB) {
// First test this bucket
for i := range bd.buckets {
for j := range shadow.buckets {
if bd.buckets[i].name == shadow.buckets[j].name {
bd.buckets[i].syncOpenBuckets(&shadow.buckets[j])
}
}
}
}
func (b *BoltBucket) syncOpenBuckets(shadow *BoltBucket) {
// First test this bucket
b.expanded = shadow.expanded
for i := range b.buckets {
for j := range shadow.buckets {
if b.buckets[i].name == shadow.buckets[j].name {
b.buckets[i].syncOpenBuckets(&shadow.buckets[j])
}
}
}
}
func (b *BoltBucket) getBucket(k string) (*BoltBucket, error) {
for i := range b.buckets {
if b.buckets[i].name == k {
@ -220,51 +302,35 @@ func (b *BoltBucket) getPair(k string) (*BoltPair, error) {
return nil, errors.New("Pair Not Found")
}
func toggleOpenBucket(path []string) error {
// Find the BoltBucket with a path == path
b, err := memBolt.getBucketFromPath(path)
if err == nil {
b.expanded = !b.expanded
}
return err
}
func closeBucket(path []string) error {
// Find the BoltBucket with a path == path
b, err := memBolt.getBucketFromPath(path)
if err == nil {
b.expanded = false
}
return err
}
func openBucket(path []string) error {
// Find the BoltBucket with a path == path
b, err := memBolt.getBucketFromPath(path)
if err == nil {
b.expanded = true
}
return err
}
func deleteKey(path []string) error {
err := db.Update(func(tx *bolt.Tx) error {
// len(b.path)-1 is the key we need to delete, the rest are buckets leading to that key
b := tx.Bucket([]byte(path[0]))
if b != nil {
if len(path) > 1 {
for i := range path[2 : len(path)-1] {
b = b.Bucket([]byte(path[i+1]))
if b == nil {
return errors.New("deleteKey: Invalid Path")
if len(path) == 1 {
// Deleting a root bucket
return tx.DeleteBucket([]byte(path[0]))
} else {
b := tx.Bucket([]byte(path[0]))
if b != nil {
if len(path) > 1 {
for i := range path[1 : len(path)-1] {
b = b.Bucket([]byte(path[i+1]))
if b == nil {
return errors.New("deleteKey: Invalid Path")
}
}
}
// Now delete the last key in the path
var err error
if delete_bkt := b.Bucket([]byte(path[len(path)-1])); delete_bkt == nil {
// Must be a pair
err = b.Delete([]byte(path[len(path)-1]))
} else {
err = b.DeleteBucket([]byte(path[len(path)-1]))
}
return err
} else {
return errors.New("deleteKey: Invalid Path")
}
// Now delete the last key in the path
err := b.Delete([]byte(path[len(path)-1]))
return err
} else {
return errors.New("deleteKey: Invalid Path")
}
})
return err

View File

@ -23,17 +23,19 @@ type BrowserScreen struct {
message string
mode BrowserMode
input_modal *termbox_util.InputModal
confirm_modal *termbox_util.ConfirmModal
}
type BrowserMode int
const (
MODE_BROWSE = 16 // 001 0000
MODE_CHANGE_VAL = 32 // 010 0000
MODE_INSERT_BUCKET = 48 // 011 0000
MODE_INSERT_PAIR = 64 // 100 0000
MODE_INSERT_PAIR_KEY = 65 // 100 0001
MODE_INSERT_PAIR_VAL = 66 // 100 0010
MODE_BROWSE = 16 // 0001 0000
MODE_CHANGE_VAL = 32 // 0010 0000
MODE_INSERT_BUCKET = 48 // 0011 0000
MODE_INSERT_PAIR = 64 // 0100 0000
MODE_INSERT_PAIR_KEY = 65 // 0100 0001
MODE_INSERT_PAIR_VAL = 66 // 0100 0010
MODE_DELETE = 128 // 1000 0000
)
type BoltType int
@ -52,7 +54,9 @@ func (screen *BrowserScreen) handleKeyEvent(event termbox.Event) int {
} else if screen.mode == MODE_CHANGE_VAL {
return screen.handleInputKeyEvent(event)
} else if screen.mode == MODE_INSERT_BUCKET {
return screen.handleInsertItemEvent(event)
return screen.handleInsertKeyEvent(event)
} else if screen.mode == MODE_DELETE {
return screen.handleDeleteKeyEvent(event)
}
return BROWSER_SCREEN_INDEX
}
@ -102,24 +106,24 @@ func (screen *BrowserScreen) handleBrowseKeyEvent(event termbox.Event) int {
if b != nil {
screen.message = "Cannot edit a bucket yet"
} else if p != nil {
screen.startEditItem(TYPE_PAIR)
screen.startEditItem()
}
} else if event.Key == termbox.KeyEnter {
b, p, _ := screen.db.getGenericFromPath(screen.current_path)
if b != nil {
toggleOpenBucket(screen.current_path)
screen.db.toggleOpenBucket(screen.current_path)
} else if p != nil {
screen.startEditItem(TYPE_PAIR)
screen.startEditItem()
}
} else if event.Ch == 'l' || event.Key == termbox.KeyArrowRight {
b, p, _ := screen.db.getGenericFromPath(screen.current_path)
// Select the current item
if b != nil {
toggleOpenBucket(screen.current_path)
screen.db.toggleOpenBucket(screen.current_path)
} else if p != nil {
screen.startEditItem(TYPE_PAIR)
screen.startEditItem()
} else {
screen.message = "Not sure what to do here..."
}
@ -128,23 +132,22 @@ func (screen *BrowserScreen) handleBrowseKeyEvent(event termbox.Event) int {
// If we are _on_ a bucket that's open, close it
b, _, e := screen.db.getGenericFromPath(screen.current_path)
if e == nil && b != nil && b.expanded {
closeBucket(screen.current_path)
screen.db.closeBucket(screen.current_path)
} else {
if len(screen.current_path) > 1 {
parent_bucket, err := screen.db.getBucketFromPath(screen.current_path[:len(screen.current_path)-1])
if err == nil {
closeBucket(parent_bucket.path)
screen.db.closeBucket(parent_bucket.path)
// Figure out how far up we need to move the cursor
screen.current_path = parent_bucket.path
}
} else {
closeBucket(screen.current_path)
screen.db.closeBucket(screen.current_path)
}
}
} else if event.Ch == 'D' {
deleteKey(screen.current_path)
screen.current_path = screen.current_path[:len(screen.current_path)-1]
screen.startDeleteItem()
}
return BROWSER_SCREEN_INDEX
}
@ -173,9 +176,50 @@ func (screen *BrowserScreen) handleInputKeyEvent(event termbox.Event) int {
return BROWSER_SCREEN_INDEX
}
func (screen *BrowserScreen) handleInsertItemEvent(event termbox.Event) int {
func (screen *BrowserScreen) handleDeleteKeyEvent(event termbox.Event) int {
screen.confirm_modal.HandleKeyPress(event)
if screen.confirm_modal.IsDone() {
if screen.confirm_modal.IsAccepted() {
hold_next_path := screen.db.getNextVisiblePath(screen.current_path)
hold_prev_path := screen.db.getPrevVisiblePath(screen.current_path)
if deleteKey(screen.current_path) == nil {
shadow_db := screen.db
screen.db = refreshDatabase()
screen.db.syncOpenBuckets(shadow_db)
// Move the current path endpoint appropriately
//found_new_path := false
if hold_next_path != nil {
if len(hold_next_path) > 2 {
if hold_next_path[len(hold_next_path)-2] == screen.current_path[len(screen.current_path)-2] {
screen.current_path = hold_next_path
} else if hold_prev_path != nil {
screen.current_path = hold_prev_path
} else {
// Otherwise, go to the parent
screen.current_path = screen.current_path[:(len(hold_next_path) - 2)]
}
} else {
// Root bucket deleted, set to next
screen.current_path = hold_next_path
}
} else if hold_prev_path != nil {
screen.current_path = hold_prev_path
} else {
screen.current_path = screen.current_path[:0]
}
}
}
screen.mode = MODE_BROWSE
screen.confirm_modal.Clear()
}
return BROWSER_SCREEN_INDEX
}
func (screen *BrowserScreen) handleInsertKeyEvent(event termbox.Event) int {
if event.Key == termbox.KeyEsc {
screen.mode = MODE_BROWSE
screen.input_modal.Clear()
} else {
/*
} else if event.Key == termbox.KeyEnter {
b, p, e := screen.db.getGenericFromPath(screen.current_path)
@ -284,6 +328,9 @@ func (screen *BrowserScreen) drawScreen(style Style) {
if screen.mode == MODE_CHANGE_VAL || screen.mode == MODE_INSERT_BUCKET || screen.mode&MODE_INSERT_PAIR == MODE_INSERT_PAIR {
screen.input_modal.Draw()
}
if screen.mode == MODE_DELETE {
screen.confirm_modal.Draw()
}
}
func (screen *BrowserScreen) drawHeader(style Style) {
@ -421,7 +468,27 @@ func (screen *BrowserScreen) drawPair(bp *BoltPair, style Style, y int) int {
return 1
}
func (screen *BrowserScreen) startEditItem(tp BoltType) bool {
func (screen *BrowserScreen) startDeleteItem() bool {
b, p, e := screen.db.getGenericFromPath(screen.current_path)
if e == nil {
w, h := termbox.Size()
inp_w, inp_h := (w / 2), 6
inp_x, inp_y := ((w / 2) - (inp_w / 2)), ((h / 2) - inp_h)
mod := termbox_util.CreateConfirmModal("", inp_x, inp_y, inp_w, inp_h, termbox.ColorWhite, termbox.ColorBlack)
if b != nil {
mod.SetTitle(termbox_util.AlignText(fmt.Sprintf("Delete Bucket '%s'?", b.name), inp_w, termbox_util.ALIGN_CENTER))
} else if p != nil {
mod.SetTitle(termbox_util.AlignText(fmt.Sprintf("Delete Pair '%s'?", p.key), inp_w, termbox_util.ALIGN_CENTER))
}
mod.SetText("This cannot be undone!")
screen.confirm_modal = mod
screen.mode = MODE_DELETE
return true
}
return false
}
func (screen *BrowserScreen) startEditItem() bool {
b, p, e := screen.db.getGenericFromPath(screen.current_path)
if e == nil {
w, h := termbox.Size()

BIN
test.db

Binary file not shown.