sqlite: pull table schema

This commit is contained in:
mappu 2024-06-08 14:23:38 +12:00
parent 232a1dd0e8
commit 00a96bfe84
3 changed files with 47 additions and 14 deletions

View File

@ -82,7 +82,7 @@ var _ loadedDatabase = &boltLoadedDatabase{} // interface assertion
//
func (f *TMainForm) addDatabaseFromFile(path string) {
func (f *TMainForm) boltAddDatabaseFromFile(path string) {
// TODO load in background thread to stop blocking the UI
db, err := bbolt.Open(path, 0644, &bbolt.Options{Timeout: 1 * time.Second})
if err != nil {

31
main.go
View File

@ -41,14 +41,19 @@ func (f *TMainForm) OnFormCreate(sender vcl.IObject) {
mnuFile.SetCaption("File")
mnuFileOpen := vcl.NewMenuItem(mnuFile)
mnuFileOpen.SetCaption("Open...")
mnuFileOpen.SetCaption("Open Bolt database...")
mnuFileOpen.SetShortCutFromString("Ctrl+O")
mnuFileOpen.SetOnClick(f.OnMnuFileOpenClick)
mnuFile.Add(mnuFileOpen)
mnuFileSqliteOpen := vcl.NewMenuItem(mnuFile)
mnuFileSqliteOpen.SetCaption("Open SQLite database...")
mnuFileSqliteOpen.SetOnClick(f.OnMnuFileSqliteOpenClick)
mnuFile.Add(mnuFileSqliteOpen)
mnuFileSqliteMemory := vcl.NewMenuItem(mnuFile)
mnuFileSqliteMemory.SetCaption("New SQLite in-memory database")
mnuFileSqliteMemory.SetOnClick(f.OnmnuFileSqliteMemoryClick)
mnuFileSqliteMemory.SetOnClick(f.OnMnuFileSqliteMemoryClick)
mnuFile.Add(mnuFileSqliteMemory)
mnuSep := vcl.NewMenuItem(mnuFile)
@ -116,21 +121,31 @@ func (f *TMainForm) OnFormCreate(sender vcl.IObject) {
func (f *TMainForm) OnMnuFileOpenClick(sender vcl.IObject) {
dlg := vcl.NewOpenDialog(f)
dlg.SetTitle("Select a database file...")
dlg.SetFilter("Bolt database|*.db|SQLite database|*.db3|All files|*.*")
dlg.SetFilter("Bolt database|*.db|All files|*.*")
ret := dlg.Execute() // Fake blocking
if ret {
f.addDatabaseFromFile(dlg.FileName())
f.boltAddDatabaseFromFile(dlg.FileName())
}
}
func (f *TMainForm) OnMnuFileSqliteOpenClick(sender vcl.IObject) {
dlg := vcl.NewOpenDialog(f)
dlg.SetTitle("Select a database file...")
dlg.SetFilter("SQLite database|*.db;*.db3;*.sqlite;*.sqlite3|All files|*.*")
ret := dlg.Execute() // Fake blocking
if ret {
f.sqliteAddDatabaseFromFile(dlg.FileName())
}
}
func (f *TMainForm) OnMnuFileSqliteMemoryClick(sender vcl.IObject) {
f.sqliteAddDatabaseFromFile(`:memory:`)
}
func (f *TMainForm) OnMnuFileExitClick(sender vcl.IObject) {
os.Exit(0)
}
func (f *TMainForm) OnmnuFileSqliteMemoryClick(sender vcl.IObject) {
f.SQLite_AddFromFile(`:memory:`)
}
func (f *TMainForm) OnNavChange(sender vcl.IObject, node *vcl.TTreeNode) {
if node.Data() == nil {

View File

@ -49,10 +49,24 @@ func (ld *sqliteLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) {
f.contentBox.SetEnabled(false)
f.contentBox.Clear()
} else if ndata.bucketPath[0] == sqliteTablesCaption {
} else if len(ndata.bucketPath) == 2 && ndata.bucketPath[0] == sqliteTablesCaption {
// Render for specific table
f.propertiesBox.SetText(fmt.Sprintf("Selected table %q", ndata.bucketPath[1]))
// Load schema
tableName := ndata.bucketPath[1]
// Get some basic properties
r := ld.db.QueryRow(`SELECT sql FROM sqlite_schema WHERE name = ?;`, tableName)
var schemaStmt string
err := r.Scan(&schemaStmt)
if err != nil {
schemaStmt = fmt.Sprintf("* Failed to describe table %q: %s", tableName, err.Error())
}
// Display table properties
f.propertiesBox.SetText(fmt.Sprintf("Selected table %q\n\nSchema:\n\n%s", tableName, schemaStmt))
// Load column details
ld.db.Query(`pragma table_info(?)`, tableName)
// Select * with small limit
f.contentBox.SetEnabled(false)
f.contentBox.Clear()
@ -71,7 +85,7 @@ func (ld *sqliteLoadedDatabase) NavChildren(ndata *navData) ([]string, error) {
return []string{sqliteTablesCaption}, nil
}
if ndata.bucketPath[0] == sqliteTablesCaption {
if len(ndata.bucketPath) == 1 && ndata.bucketPath[0] == sqliteTablesCaption {
rr, err := ld.db.Query(`SELECT name FROM sqlite_master WHERE type='table' ORDER BY name ASC;`)
if err != nil {
return nil, err
@ -95,6 +109,10 @@ func (ld *sqliteLoadedDatabase) NavChildren(ndata *navData) ([]string, error) {
return gather, nil
}
if len(ndata.bucketPath) == 2 {
return nil, nil // Never any deeper children
}
return nil, fmt.Errorf("unknown nav path %#v", ndata.bucketPath)
}
@ -102,7 +120,7 @@ var _ loadedDatabase = &sqliteLoadedDatabase{} // interface assertion
//
func (f *TMainForm) SQLite_AddFromFile(path string) {
func (f *TMainForm) sqliteAddDatabaseFromFile(path string) {
// TODO load in background thread to stop blocking the UI
db, err := sql.Open("sqlite3", path)