diff --git a/format.go b/format.go new file mode 100644 index 0000000..6007495 --- /dev/null +++ b/format.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "unicode/utf8" +) + +func formatUtf8(in []byte) string { + if !utf8.Valid(in) { + return fmt.Sprintf("<>", in) + } + + return string(in) +} + +func formatAny(in interface{}) string { + if _, ok := in.([]byte); ok { + return "<>" + } + + return fmt.Sprintf("%#v", in) +} diff --git a/main.go b/main.go index 484c0f4..c158a4e 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "strings" - "unicode/utf8" "unsafe" _ "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 } -func formatUtf8(in []byte) string { - if !utf8.Valid(in) { - return fmt.Sprintf("<>", in) - } - - return string(in) -} - func (f *TMainForm) OnNavExpanding(sender vcl.IObject, node *vcl.TTreeNode, allowExpansion *bool) { if node.Data() == nil { diff --git a/sqlite.go b/sqlite.go index 1b60388..0162f68 100644 --- a/sqlite.go +++ b/sqlite.go @@ -70,6 +70,8 @@ func (ld *sqliteLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) { // Load column details // 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) if err != nil { 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() f.contentBox.Columns().Clear() + numColumns := 0 for colr.Next() { var columnName string @@ -91,6 +94,8 @@ func (ld *sqliteLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) { col.SetCaption(columnName) col.SetWidth(MY_WIDTH) col.SetAlignment(types.TaLeftJustify) + + numColumns++ } if colr.Err() != nil { 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 // 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 f.contentBox.SetEnabled(true)