2

IN my application I use DBAware components exclusively (except a few places).

I have a scenario in which I create a Master dataset (e.g. customer), detail dataset (e.g. Orders), subdetail dataset (e.g. order items). TYpically I allow users to make changes (the dataset are in Browse mode) and then I post. Simple.

Anyway on editing the subdataset I want to add a kind of simple undo feature: one opens a form to edit the dataset (that is with db componets, so changes to the form will change the dataset), if the user Cancels the operation I would like to restore the dataset as it was before opening the form.

Now for implementing this I can think of makeing a copy of the dataset in a TClientDataSet or similar component, but are there other techiniques? Like is it possible with Delphi to create in an easy way a "snapshot" of the data. With pseudocode:

MySubDetailDataSet.SaveSnapShot;
SubDetailForm.ShowModal;
if ModalResult = mrCancel then MySubDetailDataSet.RestoreSnapShot;

Is something like that possible "off the shelf" with Delphi components?

By the way I use SDAC from DevArt components, so if you know a technique that is available only with those components and not with Delphi standard ones it is welcome!

UnDiUdin
  • 14,924
  • 39
  • 151
  • 249

4 Answers4

5

In a client dataset changes are stored in a delta - you can call CancelUpdates to clear the delta and revert to the original dataset. There are other more granular approaches. See "Undoing changes" in the help.

If you're using a RDBMS and you're properly inside a transaction, you can rollback the transaction. Some databases offer savepoints to rollback to a given savepoint instead of rolling back a whole transaction, but that's database specific. Transactions usually are per session, not per single table or query. You have to be sure only the changes you may need to roll back are performed in a given transaction.

Client dataset may be a "lighter" approach because they manage data client-side only and don't require database resources. While you're in a transaction inside the database, some resources are needed to keep track of it and changed data. Transaction should be as long as required, but not longer.

Be also aware that transactions may imply some locks. Lock management can be very different from database to database, and some may escalate locks, blocking more users than needed. Always test with a sufficient number of concurrent users to ensure transactions are used properly.

2

In AnyDAC you can do:

var
 iPrevSP: Integer;
...
iPrevSP := MySubDetailDataSet.SavePoint; 
SubDetailForm.ShowModal; 
if ModalResult = mrCancel then 
  MySubDetailDataSet.SavePoint := iPrevSP; 

The similar technique is accessible with TClientDataSet, kbmMemTable. Not the answer probably, as you are using DevArt product.

da-soft
  • 7,670
  • 28
  • 36
0

With DevArt I managed copying data to a TVitualTable (a DevArt Version of a TCLientDataSet), anyway SavePoint feature as easy as in AnyDAC is not there.

UnDiUdin
  • 14,924
  • 39
  • 151
  • 249
-1

You can use TClientDataset and load it from file or stream and save the original data inside, and every time you want to rollback, reload it from original data.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
dawood karimy
  • 179
  • 2
  • 13