redis: complete basic multidatabase browse support
This commit is contained in:
parent
8cac46e9f2
commit
5992d19906
99
db_redis.go
99
db_redis.go
@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -10,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"github.com/ying32/govcl/vcl"
|
"github.com/ying32/govcl/vcl"
|
||||||
// "github.com/ying32/govcl/vcl/types"
|
"github.com/ying32/govcl/vcl/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type redisLoadedDatabase struct {
|
type redisLoadedDatabase struct {
|
||||||
@ -42,20 +41,43 @@ func (ld *redisLoadedDatabase) Keepalive(ndata *navData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ld *redisLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
|
func (ld *redisLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
/*
|
if len(ndata.bucketPath) == 0 {
|
||||||
// Load properties
|
// Top-level: Show info() on main Properties tab
|
||||||
|
infostr, err := ld.db.Info(ctx).Result()
|
||||||
|
if err != nil {
|
||||||
|
vcl.ShowMessage(fmt.Sprintf("Retreiving database info: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
bucketDisplayName := strings.Join(ndata.bucketPath, `/`)
|
f.propertiesBox.SetText(infostr)
|
||||||
content := fmt.Sprintf("Selected database: %#v\n\n\nSelected bucket: %q\n", ld.db.Stats(), bucketDisplayName)
|
|
||||||
f.propertiesBox.SetText(content)
|
|
||||||
|
|
||||||
// Load data
|
|
||||||
|
|
||||||
|
// Disable data tab
|
||||||
f.contentBox.SetEnabled(false)
|
f.contentBox.SetEnabled(false)
|
||||||
f.contentBox.Clear()
|
f.contentBox.Clear()
|
||||||
|
|
||||||
// Bolt always uses Key + Value as the columns
|
} else if len(ndata.bucketPath) == 1 {
|
||||||
|
// One selected database
|
||||||
|
// Figure out its content
|
||||||
|
err := ld.db.Do(ctx, "SELECT", ndata.bucketPath[0]).Err()
|
||||||
|
if err != nil {
|
||||||
|
vcl.ShowMessage(fmt.Sprintf("Switching to database %q: %v", ndata.bucketPath[0], err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
allKeys, err := ld.db.Keys(ctx, "*").Result()
|
||||||
|
if err != nil {
|
||||||
|
vcl.ShowMessage(fmt.Sprintf("Listing keys in database %q: %v", ndata.bucketPath[0], err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.propertiesBox.SetText(fmt.Sprintf("Database %s\nTotal keys: %d\n", ndata.bucketPath[0], len(allKeys)))
|
||||||
|
|
||||||
|
// Redis always uses Key + Value as the columns
|
||||||
|
|
||||||
|
f.contentBox.SetEnabled(false)
|
||||||
|
f.contentBox.Clear()
|
||||||
|
|
||||||
f.contentBox.Columns().Clear()
|
f.contentBox.Columns().Clear()
|
||||||
colKey := f.contentBox.Columns().Add()
|
colKey := f.contentBox.Columns().Add()
|
||||||
@ -65,37 +87,48 @@ func (ld *redisLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
|
|||||||
colVal := f.contentBox.Columns().Add()
|
colVal := f.contentBox.Columns().Add()
|
||||||
colVal.SetCaption("Value")
|
colVal.SetCaption("Value")
|
||||||
|
|
||||||
err := ld.db.View(func(tx *bbolt.Tx) error {
|
for _, key := range allKeys {
|
||||||
b := boltTargetBucket(tx, ndata.bucketPath)
|
val, err := ld.db.Get(ctx, key).Result()
|
||||||
if b == nil {
|
if err != nil {
|
||||||
// no such bucket
|
vcl.ShowMessage(fmt.Sprintf("Listing keys in database %q: %v", ndata.bucketPath[0], err))
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid
|
dataEntry := f.contentBox.Items().Add()
|
||||||
f.contentBox.Clear()
|
dataEntry.SetCaption(key) // formatUtf8
|
||||||
|
dataEntry.SubItems().Add(val) // formatUtf8
|
||||||
c := b.Cursor()
|
|
||||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
|
||||||
dataEntry := f.contentBox.Items().Add()
|
|
||||||
dataEntry.SetCaption(formatUtf8(k))
|
|
||||||
dataEntry.SubItems().Add(formatUtf8(v))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
vcl.ShowMessage(fmt.Sprintf("Failed to load data for bucket %q: %s", bucketDisplayName, err.Error()))
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid
|
// Valid
|
||||||
f.contentBox.SetEnabled(true)*/
|
f.contentBox.SetEnabled(true)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
vcl.ShowMessage(fmt.Sprintf("Unexpected nav position %q", ndata.bucketPath))
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ld *redisLoadedDatabase) NavChildren(ndata *navData) ([]string, error) {
|
func (ld *redisLoadedDatabase) NavChildren(ndata *navData) ([]string, error) {
|
||||||
// In the bolt implementation, the nav is a recursive tree of child buckets
|
// ctx := context.Background()
|
||||||
return nil, errors.New("TODO")
|
|
||||||
//return boltChildBucketNames(ld.db, ndata.bucketPath)
|
if len(ndata.bucketPath) == 0 {
|
||||||
|
// Top-level: list of all child databases (usually 16x)
|
||||||
|
ret := make([]string, 0, ld.maxDb)
|
||||||
|
for i := 0; i < ld.maxDb; i++ {
|
||||||
|
ret = append(ret, fmt.Sprintf("%d", i))
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
|
||||||
|
} else if len(ndata.bucketPath) == 1 {
|
||||||
|
// One selected database
|
||||||
|
// No child keys underneath it
|
||||||
|
return []string{}, nil
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("Unexpected nav position %q", ndata.bucketPath)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ld *redisLoadedDatabase) ExecQuery(query string, resultArea *vcl.TListView) {
|
func (ld *redisLoadedDatabase) ExecQuery(query string, resultArea *vcl.TListView) {
|
||||||
|
Loading…
Reference in New Issue
Block a user