sqlite: load table data

This commit is contained in:
mappu 2024-06-08 15:02:02 +12:00
parent 91f9c5fc30
commit 617393b627
3 changed files with 54 additions and 10 deletions

22
format.go Normal file
View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
"unicode/utf8"
)
func formatUtf8(in []byte) string {
if !utf8.Valid(in) {
return fmt.Sprintf("<<Invalid UTF-8 %q>>", in)
}
return string(in)
}
func formatAny(in interface{}) string {
if _, ok := in.([]byte); ok {
return "<<binary>>"
}
return fmt.Sprintf("%#v", in)
}

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"unicode/utf8"
"unsafe" "unsafe"
_ "github.com/ying32/govcl/pkgs/winappres" // Extra _syso files for Windows _ "github.com/ying32/govcl/pkgs/winappres" // Extra _syso files for Windows
@ -162,14 +161,6 @@ func (f *TMainForm) OnNavChange(sender vcl.IObject, node *vcl.TTreeNode) {
ndata.ld.RenderForNav(f, ndata) // Handover to the database type's own renderer function ndata.ld.RenderForNav(f, ndata) // Handover to the database type's own renderer function
} }
func formatUtf8(in []byte) string {
if !utf8.Valid(in) {
return fmt.Sprintf("<<Invalid UTF-8 %q>>", in)
}
return string(in)
}
func (f *TMainForm) OnNavExpanding(sender vcl.IObject, node *vcl.TTreeNode, allowExpansion *bool) { func (f *TMainForm) OnNavExpanding(sender vcl.IObject, node *vcl.TTreeNode, allowExpansion *bool) {
if node.Data() == nil { if node.Data() == nil {

View File

@ -70,6 +70,8 @@ func (ld *sqliteLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
// Load column details // Load column details
// Use SELECT form instead of common PRAGMA table_info so we can just get names // Use SELECT form instead of common PRAGMA table_info so we can just get names
// We could possibly get this from the main data select, but this will
// work even when there are 0 results
colr, err := ld.db.Query(`SELECT name FROM pragma_table_info(?)`, tableName) colr, err := ld.db.Query(`SELECT name FROM pragma_table_info(?)`, tableName)
if err != nil { if err != nil {
vcl.ShowMessageFmt("Failed to load columns for table %q: %s", tableName, err.Error()) vcl.ShowMessageFmt("Failed to load columns for table %q: %s", tableName, err.Error())
@ -78,6 +80,7 @@ func (ld *sqliteLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
defer colr.Close() defer colr.Close()
f.contentBox.Columns().Clear() f.contentBox.Columns().Clear()
numColumns := 0
for colr.Next() { for colr.Next() {
var columnName string var columnName string
@ -91,6 +94,8 @@ func (ld *sqliteLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
col.SetCaption(columnName) col.SetCaption(columnName)
col.SetWidth(MY_WIDTH) col.SetWidth(MY_WIDTH)
col.SetAlignment(types.TaLeftJustify) col.SetAlignment(types.TaLeftJustify)
numColumns++
} }
if colr.Err() != nil { if colr.Err() != nil {
vcl.ShowMessageFmt("Failed to load columns for table %q: %s", tableName, err.Error()) vcl.ShowMessageFmt("Failed to load columns for table %q: %s", tableName, err.Error())
@ -99,7 +104,33 @@ func (ld *sqliteLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
colr.Close() // will be double-closed colr.Close() // will be double-closed
// Select * with small limit // Select * with small limit
// TODO datar, err := ld.db.Query(`SELECT * FROM ` + tableName + ` LIMIT 1000`) // WARNING can't prepare this parameter, but it comes from the DB (trusted)
if err != nil {
vcl.ShowMessageFmt("Failed to load data for table %q: %s", tableName, err.Error())
return
}
defer datar.Close()
for datar.Next() {
fields := make([]interface{}, numColumns)
pfields := make([]interface{}, numColumns)
for i := 0; i < numColumns; i += 1 {
pfields[i] = &fields[i]
}
err = datar.Scan(pfields...)
if err != nil {
vcl.ShowMessageFmt("Failed to load data for table %q: %s", tableName, err.Error())
return
}
dataEntry := f.contentBox.Items().Add()
dataEntry.SetCaption(formatAny(fields[0]))
for i := 1; i < len(fields); i += 1 {
dataEntry.SubItems().Add(formatAny(fields[i]))
}
}
// We successfully populated the data grid // We successfully populated the data grid
f.contentBox.SetEnabled(true) f.contentBox.SetEnabled(true)