Skip to content

dbtool: defaultBackupDir / backupDir in dbtool.yml (dbtool backup + dbtool-gui) - #663

Merged
Yaraslaut merged 6 commits into
masterfrom
feature/dbtool-default-backup-dir
Oct 7, 2026
Merged

Yaraslaut merged 6 commits into
masterfrom
feature/dbtool-default-backup-dir

Conversation

@Yaraslaut

Copy link
Copy Markdown
Member

Summary

dbtool.yml can now name where backups go, so a deployment (for example an installer) can pre-configure it and dbtool and dbtool-gui both honor it.

defaultBackupDir: D:/backups          # store-wide fallback
profiles:
  prod:
    backupDir: D:/backups/prod        # optional per-profile override

Closes #658

Resolution

Mirrors pluginsDir: the profile's backupDir, then the top-level defaultBackupDir, then the previous behaviour.

  • dbtool backup: a bare file name in --output, or no --output at all (it then writes <profile>-<YYYYMMDD-HHMMSS>.zip, local time), goes into that folder, which is created if missing. A path with a directory part is used exactly as given. The file that was written is printed. With no folder configured --output is required, as before.
  • dbtool add-profile --backup-dir <DIR>, and list-profiles shows an effective BACKUPDIR column.
  • dbtool-gui: defaultBackupDir becomes the default backup folder, unless a folder was chosen in Settings (which still wins). Settings' placeholder and help show the folder that will really be used.
  • Docs: docs/dbtool.md and the GUI README.

Decisions worth a look

  • GUI and per-profile backupDir. The Backups page keeps every profile's archive in one folder (one folder card, one folder check, <profile>.zip inside it), so only the store-wide defaultBackupDir applies there; a per-profile backupDir is a CLI feature. Honoring it in the GUI would mean a per-profile folder model, which felt out of scope. The issue's "use the resolved folder" is ambiguous on this, so I took the reading that does not change the page's model. Say if you want the other one.
  • --connection-string without --profile applies no profile, and therefore no backup folder, like every other profile default. --output stays required there.
  • Relative paths are used as written (relative to the working directory), like pluginsDir.
  • Bug found on the way. ProfileFileEditor listed the fields of a new profile in two places: the text it renders, and the document it verifies its own edit against. Adding a field to only one made every add-profile that carried it fail with "could not be edited exactly". Both now come from one table, so they cannot drift apart again.

Performance impact

None: configuration parsing and a path decision.

Risk assessment

  • Per DBMS: none, no database code changed.
  • Behaviour change: only for files that contain the new keys. Without them dbtool backup behaves exactly as before. Profile and NewProfile gained a defaulted field at the end, so existing aggregate initialisations are unaffected.
  • Generated name: uses local time and replaces characters that are unsafe in a file name with _.
  • Overlap with dbtool-gui: Backup & restore panel, Settings in Simple mode, add profiles #662. That PR also changes dbtool/main.cpp's add-profile (it moves it onto a shared AddProfileToFile) and ProfileFileEditorTests.cpp. Whichever merges second needs a small rebase: ProfileRequest there will need a backupDir field and the --backup-dir wiring moved onto it. I kept this PR on master so it does not depend on dbtool-gui: Backup & restore panel, Settings in Simple mode, add profiles #662.

Testing

  • Suites run locally (Windows clang-cl, release, SQLite): the new [backup-dir] tests, [ProfileStore], [ProfileFileEditor], [profile-add], test_dbtool.py --test-env sqlite3 (which now covers add-profile --backup-dir, list-profiles, bare name, generated name, explicit path, defaultBackupDir fallback and the unchanged error without a folder), and the dbtool-gui Catch2 and QML suites.
  • Linux, Qt 6.8.0, clang 19: dbtool, dbtool-gui and the GUI test targets (Catch2, QML, smoke) build and pass.
  • Not run: GCC (the WSL GCC tree cannot configure here, no OpenSSL dev headers), clang-tidy, MSSQL and PostgreSQL, the C++26 reflection and modules builds. No database code changed.
  • Known local failures unrelated to this change: two existing GUI tests assume no profile is loaded but the developer's real %APPDATA%\dbtool\dbtool.yml is auto-discovered. They pass on CI and on Linux.
  • /simplify was not run.

🤖 Generated with Claude Code

Yaraslau Tamashevich and others added 2 commits October 6, 2026 20:28
…l backup` (#658)

dbtool.yml can now name where backups go, so a deployment (an installer, say)
can pre-configure it:

    defaultBackupDir: D:/backups        # store-wide fallback
    profiles:
      prod:
        backupDir: D:/backups/prod      # per-profile override

Resolution mirrors pluginsDir: the profile's backupDir, else defaultBackupDir.

- ProfileStore parses and saves both keys (a blank key means none) and offers
  EffectiveBackupDir(profile).
- `dbtool backup`: a bare file name in --output, or no --output at all (it then
  writes <profile>-<YYYYMMDD-HHMMSS>.zip), goes into that folder, which is
  created if missing; a path with a directory part is used as given. The pure
  decision lives in Config::ResolveBackupOutput, so it is tested without I/O.
  Without a configured folder, --output is required as before.
- `dbtool add-profile --backup-dir <DIR>` and `list-profiles` (BACKUPDIR column).
- ProfileFileEditor writes backupDir. Its rendered fields and the document it
  verifies its own edit against now come from one table: the verification list
  was a second copy and refused every edit that carried the new field.

Tests: store parsing, precedence and round trip; the editor; the resolution rules
and generated names; and test_dbtool.py end to end (add-profile --backup-dir,
list-profiles, bare name, generated name, explicit path, defaultBackupDir
fallback, and the unchanged error without a folder).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
When no folder was chosen in Settings, the default backup folder is now the
defaultBackupDir of the loaded dbtool.yml if it names one, else the platform
default. AppController pushes it to ManagedBackupController on every profile
reload, and Settings' placeholder / help text show the folder that will really
be used. A folder chosen in Settings still wins.

A per-profile backupDir is not used here: the Backups page keeps every
profile's archive in one folder.

Tests: ManagedBackupController (configured vs chosen vs platform default) and
AppController (loading a file with and without the key).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Yaraslaut
Yaraslaut requested a review from a team as a code owner October 6, 2026 18:33
@github-actions github-actions Bot added documentation Improvements or additions to documentation CLI command line interface tools tests labels Oct 6, 2026
@codecov

codecov Bot commented Oct 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Yaraslau Tamashevich and others added 4 commits October 7, 2026 14:08
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Carry backupDir through ProfileRequest, which master introduced for add-profile.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…r in ProfileRequest literals

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Yaraslaut
Yaraslaut merged commit 929d053 into master Oct 7, 2026
30 checks passed
@Yaraslaut
Yaraslaut deleted the feature/dbtool-default-backup-dir branch October 7, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLI command line interface tools documentation Improvements or additions to documentation tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dbtool.yml: support a default backup folder (defaultBackupDir / profile backupDir)

1 participant