feat: rename/relocate a profile's SQLite logbook (QSOs carried across)
"Choose a dedicated file" points at a fresh/empty file; there was no way to rename or move an existing logbook WITH its data. RenameLogbook VACUUM INTOs the active profile's SQLite logbook to a new path, repoints the profile and switches the live logbook (no restart). Deletes the old file only when it was a dedicated per-profile file; the shared default logbook.db is left for other profiles. Errors on a MySQL logbook. UI: "Rename / relocate…" button in the logbook section.
This commit is contained in:
@@ -1806,6 +1806,61 @@ func (a *App) SaveMySQLSettings(s MySQLSettings) error {
|
||||
return a.switchLogbook(p)
|
||||
}
|
||||
|
||||
// RenameLogbook copies the ACTIVE profile's SQLite logbook to dest (with its
|
||||
// QSOs), repoints the profile at it and switches the live logbook — no restart.
|
||||
// Unlike "choose a dedicated file" (which points at a fresh/empty file), this
|
||||
// carries the data across. The old file is deleted only when it was this
|
||||
// profile's OWN dedicated file; the shared default logbook.db is left in place
|
||||
// (other profiles may use it). Errors if the logbook is MySQL.
|
||||
func (a *App) RenameLogbook(dest string) error {
|
||||
dest = strings.TrimSpace(dest)
|
||||
if dest == "" {
|
||||
return fmt.Errorf("no destination given")
|
||||
}
|
||||
p, err := a.profiles.Active(a.ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("no active profile: %w", err)
|
||||
}
|
||||
if p.DB.Backend == "mysql" {
|
||||
return fmt.Errorf("this profile's logbook is MySQL — no file to rename")
|
||||
}
|
||||
old := strings.TrimSpace(p.DB.Path)
|
||||
wasDedicated := old != ""
|
||||
if old == "" {
|
||||
old = a.logbookPath
|
||||
}
|
||||
if old == "" || a.logDb == nil {
|
||||
return fmt.Errorf("no logbook file to rename")
|
||||
}
|
||||
if strings.EqualFold(filepath.Clean(dest), filepath.Clean(old)) {
|
||||
return fmt.Errorf("that is already the current logbook name")
|
||||
}
|
||||
if _, err := os.Stat(dest); err == nil {
|
||||
return fmt.Errorf("a file already exists at %s — pick a new name", dest)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
|
||||
return fmt.Errorf("create folder: %w", err)
|
||||
}
|
||||
safe := strings.ReplaceAll(dest, "'", "''")
|
||||
if _, err := a.logDb.ExecContext(a.ctx, "VACUUM INTO '"+safe+"'"); err != nil {
|
||||
return fmt.Errorf("copy logbook: %w", err)
|
||||
}
|
||||
p.DB.Backend = "sqlite"
|
||||
p.DB.Path = dest
|
||||
if err := a.profiles.SetDB(a.ctx, p.ID, p.DB); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := a.switchLogbook(p); err != nil { // opens dest, closes the old conn
|
||||
return err
|
||||
}
|
||||
if wasDedicated {
|
||||
for _, f := range []string{old, old + "-wal", old + "-shm"} {
|
||||
_ = os.Remove(f)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestMySQLConnection pings the shared MySQL database with the given settings
|
||||
// (no migrations) so the user can validate connectivity from the UI.
|
||||
func (a *App) TestMySQLConnection(s MySQLSettings) error {
|
||||
|
||||
Reference in New Issue
Block a user