From ce3d08740fac31e0d0f927036b35ff9404bf2eae Mon Sep 17 00:00:00 2001 From: mappu Date: Sun, 14 Jul 2024 15:34:17 +1200 Subject: [PATCH] sqlite: add context actions for compact, export, drop table --- db_sqlite.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- util_vcl.go | 27 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/db_sqlite.go b/db_sqlite.go index bf50e50..b366aa4 100644 --- a/db_sqlite.go +++ b/db_sqlite.go @@ -229,8 +229,52 @@ func (ld *sqliteLoadedDatabase) NavChildren(ndata *navData) ([]string, error) { return nil, fmt.Errorf("unknown nav path %#v", ndata.bucketPath) } -func (ld *sqliteLoadedDatabase) NavContext(ndata *navData) ([]contextAction, error) { - return nil, nil // No special actions are supported +func (ld *sqliteLoadedDatabase) NavContext(ndata *navData) (ret []contextAction, err error) { + + if len(ndata.bucketPath) == 0 { + ret = append(ret, contextAction{"Compact database", ld.CompactDatabase}) + ret = append(ret, contextAction{"Export backup...", ld.ExportBackup}) + } + if len(ndata.bucketPath) == 2 { + ret = append(ret, contextAction{"Drop table", ld.DropTable}) + } + return +} + +func (ld *sqliteLoadedDatabase) CompactDatabase(sender vcl.IComponent, ndata *navData) error { + _, err := ld.db.Exec(`VACUUM;`) + return err +} + +func (ld *sqliteLoadedDatabase) ExportBackup(sender vcl.IComponent, ndata *navData) error { + // Popup for output file + dlg := vcl.NewSaveDialog(sender) + dlg.SetTitle("Save backup as...") + dlg.SetFilter(sqliteFilter) + ret := dlg.Execute() // Fake blocking + if !ret { + return nil // cancelled + } + + _, err := ld.db.Exec(`VACUUM INTO ?`, dlg.FileName()) + return err +} + +func (ld *sqliteLoadedDatabase) DropTable(sender vcl.IComponent, ndata *navData) error { + if len(ndata.bucketPath) != 2 { + return errors.New("Invalid selection") + } + + // + + tableName := ndata.bucketPath[1] + + if !vcl_confirm_dialog(sender, "Drop table", fmt.Sprintf("Are you sure you want to drop the table %q?", tableName)) { + return nil // cancelled + } + + _, err := ld.db.Exec(`DROP TABLE "` + tableName + `"`) // WARNING can't prepare this parameter, but it comes from the DB (trusted) + return err } func (ld *sqliteLoadedDatabase) Close() { diff --git a/util_vcl.go b/util_vcl.go index d650f90..ba5c562 100644 --- a/util_vcl.go +++ b/util_vcl.go @@ -90,3 +90,30 @@ func vcl_stringgrid_columnwidths(d *vcl.TStringGrid) { } } } + +func vcl_confirm_dialog(sender vcl.IComponent, title string, message string) bool { + + dlg := vcl.NewTaskDialog(sender) + dlg.SetCaption(APPNAME) + dlg.SetTitle(title) + dlg.SetText(message) + dlg.SetCommonButtons(types.NewSet()) + + yesBtn := dlg.Buttons().Add() + yesBtn.SetCaption("Confirm") + yesBtn.SetModalResult(types.MrYes) + + noBtn := dlg.Buttons().Add() + noBtn.SetCaption("Cancel") + noBtn.SetModalResult(types.MrCancel) + + ret := dlg.Execute() + if !ret { + return false // dialog closed + } + if dlg.ModalResult() != types.MrYes { + return false // other button clicked + } + + return true // confirmed +}