add new custom query feature

This commit is contained in:
mappu 2024-06-15 12:14:11 +12:00
parent 38847b3a7e
commit ef30a0d210
4 changed files with 80 additions and 0 deletions

View File

@ -94,6 +94,10 @@ func (ld *boltLoadedDatabase) NavChildren(ndata *navData) ([]string, error) {
return boltChildBucketNames(ld.db, ndata.bucketPath) return boltChildBucketNames(ld.db, ndata.bucketPath)
} }
func (ld *boltLoadedDatabase) ExecQuery(query string, resultArea *vcl.TListView) {
vcl.ShowMessage("Bolt doesn't support querying")
}
var _ loadedDatabase = &boltLoadedDatabase{} // interface assertion var _ loadedDatabase = &boltLoadedDatabase{} // interface assertion
// //

View File

@ -10,6 +10,7 @@ type loadedDatabase interface {
DriverName() string DriverName() string
RootElement() *vcl.TTreeNode RootElement() *vcl.TTreeNode
RenderForNav(f *TMainForm, ndata *navData) RenderForNav(f *TMainForm, ndata *navData)
ExecQuery(query string, resultArea *vcl.TListView)
NavChildren(ndata *navData) ([]string, error) NavChildren(ndata *navData) ([]string, error)
Keepalive(ndata *navData) Keepalive(ndata *navData)
} }

52
main.go
View File

@ -12,6 +12,7 @@ import (
const ( const (
MY_SPACING = 6 MY_SPACING = 6
MY_HEIGHT = 90
MY_WIDTH = 180 MY_WIDTH = 180
) )
@ -25,6 +26,8 @@ type TMainForm struct {
Tabs *vcl.TPageControl Tabs *vcl.TPageControl
propertiesBox *vcl.TMemo propertiesBox *vcl.TMemo
contentBox *vcl.TListView contentBox *vcl.TListView
queryInput *vcl.TMemo
queryResult *vcl.TListView
dbs []loadedDatabase dbs []loadedDatabase
} }
@ -132,6 +135,43 @@ func (f *TMainForm) OnFormCreate(sender vcl.IObject) {
f.contentBox.SetAutoWidthLastColumn(true) f.contentBox.SetAutoWidthLastColumn(true)
f.contentBox.SetReadOnly(true) f.contentBox.SetReadOnly(true)
f.contentBox.Columns().Clear() f.contentBox.Columns().Clear()
queryTab := vcl.NewTabSheet(f.Tabs)
queryTab.SetParent(f.Tabs)
queryTab.SetCaption("Query")
queryTab.SetImageIndex(imgLightning)
queryExecBtn := vcl.NewButton(queryTab)
queryExecBtn.SetParent(queryTab)
queryExecBtn.SetCaption("Execute")
queryExecBtn.SetAlign(types.AlTop)
queryExecBtn.SetOnClick(f.OnQueryExecute)
f.queryInput = vcl.NewMemo(queryTab)
f.queryInput.SetParent(queryTab)
f.queryInput.SetHeight(MY_HEIGHT)
f.queryInput.SetAlign(types.AlTop)
f.queryInput.SetTop(1)
f.queryInput.Font().SetName("monospace")
f.queryInput.BorderSpacing().SetLeft(MY_SPACING)
f.queryInput.BorderSpacing().SetTop(MY_SPACING)
f.queryInput.BorderSpacing().SetRight(MY_SPACING)
vsplit := vcl.NewSplitter(queryTab)
vsplit.SetParent(queryTab)
vsplit.SetAlign(types.AlTop)
vsplit.SetTop(2)
f.queryResult = vcl.NewListView(queryTab)
f.queryResult.SetParent(queryTab)
f.queryResult.SetAlign(types.AlClient) // fill remaining space
f.queryResult.SetViewStyle(types.VsReport) // "Report style" i.e. has columns
f.queryResult.SetAutoWidthLastColumn(true)
f.queryResult.SetReadOnly(true)
f.queryResult.Columns().Clear()
f.queryResult.BorderSpacing().SetLeft(MY_SPACING)
f.queryResult.BorderSpacing().SetRight(MY_SPACING)
f.queryResult.BorderSpacing().SetBottom(MY_SPACING)
} }
func (f *TMainForm) OnMnuFileOpenClick(sender vcl.IObject) { func (f *TMainForm) OnMnuFileOpenClick(sender vcl.IObject) {
@ -162,6 +202,18 @@ func (f *TMainForm) OnMnuFileExitClick(sender vcl.IObject) {
f.Close() f.Close()
} }
func (f *TMainForm) OnQueryExecute(sender vcl.IObject) {
// Execute
node := f.Buckets.Selected()
if node == nil {
vcl.ShowMessage("No database selected")
return
}
ndata := (*navData)(node.Data())
ndata.ld.ExecQuery(f.queryInput.Text(), f.queryResult)
}
func (f *TMainForm) OnNavChange(sender vcl.IObject, node *vcl.TTreeNode) { func (f *TMainForm) OnNavChange(sender vcl.IObject, node *vcl.TTreeNode) {
if node.Data() == nil { if node.Data() == nil {

View File

@ -173,6 +173,29 @@ func populateRows(rr *sql.Rows, dest *vcl.TListView) {
} }
} }
func (ld *sqliteLoadedDatabase) ExecQuery(query string, resultArea *vcl.TListView) {
rr, err := ld.db.Query(query)
if err != nil {
vcl.ShowMessage(err.Error())
return
}
defer rr.Close()
resultArea.SetEnabled(false)
resultArea.Clear()
columns, err := rr.Columns()
if err != nil {
vcl.ShowMessage(err.Error())
return
}
populateColumns(columns, resultArea)
populateRows(rr, resultArea)
resultArea.SetEnabled(true)
} }
func (ld *sqliteLoadedDatabase) NavChildren(ndata *navData) ([]string, error) { func (ld *sqliteLoadedDatabase) NavChildren(ndata *navData) ([]string, error) {