sqlite: pull table schema
This commit is contained in:
parent
232a1dd0e8
commit
00a96bfe84
2
bolt.go
2
bolt.go
@ -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
31
main.go
@ -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 {
|
||||
|
28
sqlite.go
28
sqlite.go
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user