I'd like to have a cancelable "pack database" in my app. I am assuming that this would entail making a backup copy of my database before calling IVistaDBDDA.PackDatabase. I'm further assuming that if my OperationCallbackDelegate throws an exception that this will cause PackDatabase to fail & bail out early, leaving the database in an indeterminate state - which is fine since I'll make a backup before starting.
Any problem with this approach?
Oh yes! Backups are a must! End user responsibility - this is an interactive desktop app, so the user can easily make backup copies of their databases. Thanks for the follow-up.
You should still consider using backups, though. If the block-copy phase gets interrupted, then having a backup from before the pack can be your only recourse.
Making a backup copy is easy to do while all connections are closed before (and perhaps again after) a pack, as long as you have the space for them.
Thanks for the detailed reply. Since PackDatabase already works in a failsafe manner (or at least mostly), I won't bother wrapping my own safety around it and I'll forego cancellation tor now.
Adding an officially endorsed mechanism for cancellation of pack database is definitely the better solution long term - consider this a feature request :)
I'd have to check the code as to whether an exception in the callback will cause a failure or is wrapped in a try/catch, but I suspect the latter is more likely because a mistake causing an exception in the callback is possible and should not be allowed to break a PackDatabase operation, so it should already be guarding against that. So, my guess is that an attempt to "abort" a PackDatabase by throwing an exception in the callback method will not work.
The PackDatabase builds a new database in a temporary file and copies the schema and data into it. Callbacks are invoked periodically during this phase. When the rebuilding phase is done, the contents of the temporary file are block-copied back onto the original database file. This latter phase is when it is most vulnerable because an interruption would leave the database file with two incompatible versions of the data inter-mixed, and such a database is very hard to recover meaningful data from. I'm not sure whether there are any progress callback calls during the block-copy phase--I think it's a tight loop with no callbacks, but I'd have to double-check.
I don't recommend the approach you're suggesting, but you could experiment with trying it and see how it goes.
As a better solution, we could try to add support for a CancellationToken in the PackDatabase overloads which could abort the pack at any safe point during the rebuilding phase and perform any needed cleanup.