C# dataset redo change
I have added the capabilty to be able to undo. I am now trying to add the capabilty to redo the change after an update , insert or delete to the dataset or database
Know the answer? Post it — somebody with the same question will find it here.
Sign in to answer this question
It is the same account you read, post and publish with — and you will come straight back to this page.
Zoran HorvatPosted Jul 25, 2011, 4:56 PM
Has the post above answered your question or do you need other explanations?
Zoran
Zoran HorvatPosted Jul 21, 2011, 12:16 PM
Undo/redo functionality is quite straight forward but there is (probably) no ready to use code which would help you too much about that.
Generally, undoing and redoing actions on data means that you put a very formal definition on your data. Then actions can be defined in a formal way as well.
For instance, if there is one table named Person, then actions can be defined as:
Create person(person_id, name, surname) - it receives person id on output; name and surname are values of name and surname inserted
Update person(person_id, name, surname, prev_name, prev_surname) - means that person with prev name and prev surname, whos ID is person id should be renamed to name and surname
Delete person(person_id, name surname) - means that person with given name and surname and with given person id is deleted
Now you have Do and Undo operations on these action descriptions:
Create person DO action is: INSERT INTO Person(Name, Surname) VALUES(name, surname); SELECT person id = @@IDENTITY;
Create person UNDO action is: DELETE FROM Person WHERE PersonID=person_id
Update person DO action is: SELECT prev_name = Name, prev_surname = Surname WHERE PersonID=person_id; UPDATE Person SET Name=name, Surname=surname WHERE PersonID=person_id;
Update person UNDO action is: UPDATE Person SET Name=prev_name, Surname=prev_surname WHERE PersonID=person_id;
Delete person DO action is: SELECT name=Name, surname=Surname FROM Person WHERE PersonID=person_id; DELETE FROM Person WHERE PersonID=person_id;
Delete person UNDO action is: INSERT INTO Person(Name, Surname) VALUES (name, surname); SELECT person_id=@@IDENTITY;
Then your application maintains array of actions in their chronological order and maintains current position. Operations on this structure are:
1. User performs completely new operation - then create DO action and UNDO action tandem for that operation; delete all operations to the right of current operation and insert new operation to the end of the structure. Move current position beyond this operation.
2. User tries to undo last change - If there is operation to the left of the current position, then move current position by one to the left and perform UNDO action from that item.
3. User tries to redo change - If there is operation to the right of current position then execute its DO action and move current position to the right; If current position is at the end of the array and there is at least one operation to the left, then execute last operation's DO action - that would be redo operation in sense like "repeat what I did last".
Hope this explains the matters. Again, there is not much to expect from ready to use libraries or similar stuff. This is simply because DO and UNDO operations are strictly data-dependant, i.e. heavily depend on data manipulated by your application, which one might not be able to generalize.
One more note for the end. Executing operations on database may lead you to unholy situation of concurrent edit. This happens for example if you try to undo Create person operation, but there is no person with specified person_id. This happens if somebody has deleted that person from another instance of the operation. So your implementations must always test whether record being done/undone exists in the database and only then carry on the operation. Otherwise, you must present user the convenient "concurrent edit in progress" message, which may require purging or at least validating all items in the undo/redo array. This is not easy task to do, and especially not easy to generalize.
Zoran