2024-06-30 02:14:41 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
indexes := make(map[string]int)
|
|
|
|
|
|
|
|
for i, cname := range ld.db.AllColumnNames {
|
|
|
|
indexes[cname] = i
|
|
|
|
|
|
|
|
col := f.contentBox.Columns().Add()
|
2024-07-05 07:21:08 +00:00
|
|
|
col.Title().SetCaption(cname)
|
2024-06-30 02:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, entry := range ld.db.Entries {
|
|
|
|
|
2024-07-05 07:21:08 +00:00
|
|
|
rpos := f.contentBox.RowCount()
|
|
|
|
f.contentBox.SetRowCount(rpos + 1)
|
|
|
|
f.contentBox.SetCells(0, rpos, entry.Name)
|
2024-06-30 02:14:41 +00:00
|
|
|
|
|
|
|
for _, proppair := range entry.Properties {
|
2024-07-05 07:21:08 +00:00
|
|
|
f.contentBox.SetCells(int32(indexes[proppair[0]]), rpos, proppair[1])
|
2024-06-30 02:14:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Valid
|
2024-07-05 07:35:24 +00:00
|
|
|
vcl_stringgrid_columnwidths(f.contentBox)
|
2024-06-30 02:14:41 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-07-05 07:21:08 +00:00
|
|
|
func (ld *debconfLoadedDatabase) ExecQuery(query string, resultArea *vcl.TStringGrid) {
|
2024-06-30 02:14:41 +00:00
|
|
|
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)
|
|
|
|
}
|