- Log the "transaction already completed/disposed" cases as warnings instead of
verbose messages, so they are captured in tests and the underlying issue can be
fixed (per review feedback).
- Replace the fragile message-string matching in IsInactiveTransactionException
with an exception-type check. Microsoft.Data.Sqlite throws InvalidOperationException
("This SqliteTransaction has completed; it is no longer usable.") for an
already-completed transaction; matching the type avoids breaking under
localization or matching unintended messages (verified locally via the Issue5827
test, which catches System.InvalidOperationException).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This refactors a part of the database and adds a new "sync" command that reuses a lot of the backup logic to take a set of sources and apply them to a backend.
Unlike the backup process, the sync copies files verbatim without any encryption.
The main idea was to remove internal use of nullable, and to only have one implementation; which is why the synchronous versions call the asynchronous versions.
Rewrote all operation handlers to be async.
This moves the async/sync threshold out into the controller.
Fixed all the uses of cancellation token in the handlers to use the provided cancellation token.
Introduced a new ReusableTransaction that can be passed around, avoiding a ref parameter passing of the transaction instance.