debconf: add as database option

This commit is contained in:
mappu 2024-06-30 14:14:41 +12:00
parent 1cfc94a42b
commit 063a8ca837
4 changed files with 166 additions and 0 deletions

BIN
assets/vendor_debian.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

142
db_debconf.go Normal file
View File

@ -0,0 +1,142 @@
package main
import (
"fmt"
"os"
"path/filepath"
"unsafe"
"yvbolt/debconf"
"github.com/ying32/govcl/vcl"
)
type debconfLoadedDatabase struct {
displayName string
db *debconf.Database
nav *vcl.TTreeNode
arena []*navData // keepalive
}
func (ld *debconfLoadedDatabase) DisplayName() string {
return ld.displayName
}
func (ld *debconfLoadedDatabase) DriverName() string {
return "debconf"
}
func (ld *debconfLoadedDatabase) RootElement() *vcl.TTreeNode {
return ld.nav
}
func (ld *debconfLoadedDatabase) Keepalive(ndata *navData) {
ld.arena = append(ld.arena, ndata)
}
func (ld *debconfLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
// Load properties
content := fmt.Sprintf("Entries: %d\nUnique attributes: %d\n", len(ld.db.Entries), len(ld.db.AllColumnNames))
f.propertiesBox.SetText(content)
// Load data
f.contentBox.SetEnabled(false)
f.contentBox.Clear()
// debconf always uses Key + Value as the columns
indexes := make(map[string]int)
f.contentBox.Columns().Clear()
for i, cname := range ld.db.AllColumnNames {
indexes[cname] = i
col := f.contentBox.Columns().Add()
col.SetCaption(cname)
col.SetWidth(MY_WIDTH)
}
for _, entry := range ld.db.Entries {
cell := f.contentBox.Items().Add()
cell.SetCaption(entry.Name)
texts := make([]string, len(ld.db.AllColumnNames))
for _, proppair := range entry.Properties {
texts[indexes[proppair[0]]-1 /* compensate for 'Name' always being first */] = proppair[1]
}
cell.SubItems().AddStrings2(texts)
}
// Valid
f.contentBox.SetEnabled(true)
}
func (ld *debconfLoadedDatabase) NavChildren(ndata *navData) ([]string, error) {
// In the debconf implementation, there is only one child: "Data"
if len(ndata.bucketPath) == 0 {
return []string{"Data"}, nil
} else {
// No children deeper than that
return []string{}, nil
}
}
func (ld *debconfLoadedDatabase) NavContext(ndata *navData) ([]contextAction, error) {
return nil, nil // No special actions are supported
}
func (ld *debconfLoadedDatabase) ExecQuery(query string, resultArea *vcl.TListView) {
vcl.ShowMessage("debconf doesn't support querying")
}
func (ld *debconfLoadedDatabase) Close() {
ld.arena = nil
}
var _ loadedDatabase = &debconfLoadedDatabase{} // interface assertion
//
func (f *TMainForm) debconfAddDatabaseFrom(path string) {
// TODO load in background thread to stop blocking the UI
fh, err := os.OpenFile(path, os.O_RDONLY, 0400)
if err != nil {
vcl.ShowMessage(fmt.Sprintf("Failed to load database: %s", err.Error()))
return
}
defer fh.Close()
db, err := debconf.Parse(fh)
if err != nil {
vcl.ShowMessage(fmt.Sprintf("Failed to load database: %s", err.Error()))
return
}
ld := &debconfLoadedDatabase{
db: db,
displayName: filepath.Base(path),
}
ld.nav = f.Buckets.Items().Add(nil, ld.displayName)
ld.nav.SetHasChildren(true) // dynamically populate in OnNavExpanding
ld.nav.SetImageIndex(imgDatabase)
ld.nav.SetSelectedIndex(imgDatabase)
navData := &navData{
ld: ld,
childrenLoaded: false, // will be loaded dynamically
bucketPath: []string{}, // empty = root
}
ld.nav.SetData(unsafe.Pointer(navData))
f.dbs = append(f.dbs, ld)
f.Buckets.SetSelected(ld.nav) // Select new element
ld.Keepalive(navData)
}

View File

@ -23,6 +23,7 @@ const (
imgTableDelete imgTableDelete
imgTableSave imgTableSave
imgVendorCockroach imgVendorCockroach
imgVendorDebian
imgVendorDgraph imgVendorDgraph
imgVendorGithub imgVendorGithub
imgVendorMySQL imgVendorMySQL
@ -60,6 +61,7 @@ func loadImages(owner vcl.IComponent) *vcl.TImageList {
ilist.Add(mustLoad("assets/table_delete.png"), nil) ilist.Add(mustLoad("assets/table_delete.png"), nil)
ilist.Add(mustLoad("assets/table_save.png"), nil) ilist.Add(mustLoad("assets/table_save.png"), nil)
ilist.Add(mustLoad("assets/vendor_cockroach.png"), nil) ilist.Add(mustLoad("assets/vendor_cockroach.png"), nil)
ilist.Add(mustLoad("assets/vendor_debian.png"), nil)
ilist.Add(mustLoad("assets/vendor_dgraph.png"), nil) ilist.Add(mustLoad("assets/vendor_dgraph.png"), nil)
ilist.Add(mustLoad("assets/vendor_github.png"), nil) ilist.Add(mustLoad("assets/vendor_github.png"), nil)
ilist.Add(mustLoad("assets/vendor_mysql.png"), nil) ilist.Add(mustLoad("assets/vendor_mysql.png"), nil)

22
main.go
View File

@ -79,6 +79,15 @@ func (f *TMainForm) OnFormCreate(sender vcl.IObject) {
// //
mnuFileDebconf := vcl.NewMenuItem(mnuFile)
mnuFileDebconf.SetCaption("Debconf")
mnuFileDebconf.SetImageIndex(imgVendorDebian)
mnuFile.Add(mnuFileDebconf)
vcl_menuitem(mnuFileDebconf, "Open database...", imgDatabaseAdd, f.OnMnuFileDebianOpenClick)
//
mnuFilePebble := vcl.NewMenuItem(mnuFile) mnuFilePebble := vcl.NewMenuItem(mnuFile)
mnuFilePebble.SetCaption("Pebble") mnuFilePebble.SetCaption("Pebble")
mnuFilePebble.SetImageIndex(imgVendorCockroach) mnuFilePebble.SetImageIndex(imgVendorCockroach)
@ -328,6 +337,19 @@ func (f *TMainForm) OnMnuFilePebbleOpenClick(sender vcl.IObject) {
} }
} }
func (f *TMainForm) OnMnuFileDebianOpenClick(sender vcl.IObject) {
dlg := vcl.NewOpenDialog(f)
dlg.SetTitle("Select a database file...")
dlg.SetFilter("Debconf database|*.dat|All files|*.*")
if runtime.GOOS == "linux" {
dlg.SetInitialDir(`/var/cache/debconf/`)
}
ret := dlg.Execute() // Fake blocking
if ret {
f.debconfAddDatabaseFrom(dlg.FileName())
}
}
func (f *TMainForm) OnMnuFilePebbleMemoryClick(sender vcl.IObject) { func (f *TMainForm) OnMnuFilePebbleMemoryClick(sender vcl.IObject) {
f.pebbleAddDatabaseFromMemory() f.pebbleAddDatabaseFromMemory()
} }