How to utilize sqlite for undo/redo features?
Asked Answered
R

4

5

I'm writing a desktop application to do vector drawing in C++, and considering using sqlite to back my undo/redo feature.

Has anybody used sqlite for undo/redo features? How does it work out for you?

Clarification:

I was aware of the stack approach, I have even implemented one application with that approach. The problem I encountered was that it becomes hard to maintain after a while.

What I meant by utilizing sqlite is that I will map my entire in-memory data structure into a sqlite database, and let the sqlite do the diff and revision for me. Speed should not be a issue if I create a in-memory database.

That was the idea and I was wondering if that could work.

Rupiah answered 31/3, 2009 at 13:10 Comment(3)
That does seem overkill. What's wrong with the normal bounded stack/command pattern approach?Lammers
c2.com/cgi/wiki?AbstractionInversionLammers
I agree with Pete. Start out with a stack-based approach; if that doesn't cut it, look at giving each command the ability to serialise/deserialise itself to a DB. But really, unless you're doing something really strange, The stack-based approach will cut it.Constipation
G
13

It makes sense to use SQLite to back undo/redo when an SQLite database is the application's data file format. See the SQLite website for an explanation of how to do this with SQLite triggers.

Greyhen answered 31/3, 2009 at 22:23 Comment(2)
I would have given vote this reply up if I had more than 15 reputation.Rupiah
If you are happy to use a GPL licensed library, there is a source-forge project that has done lots of work for you. (I haven't used it yet; I just read the docs.) You can find it at sourceforge.net/projects/sqlite-undoJournalist
D
2

Basically a undo/redo feature can be implemented using a stack: when the user does an operation, you push on the stack an object that represents the delta between the state before and after the operation, and when you undo, you "unroll" the delta. Because every operation the user does creates a new delta object on the stack, it might by that sqlite is not your choice of technology because it might be too slow. I would recommend considering the possibility of just storing the undo/redo information in memory, and linearizing it on the disk only if you want to actually save the undo/redo history.

Doering answered 31/3, 2009 at 13:15 Comment(3)
Not necessarily the best approach for a graphics app. Knowing that the last operation was change every pixel to black isn't enough to undo the operation.Deirdra
@mgb Of course not---but that's not how you do it anyway. An unoptimized implementation would have a basic operation of changing the color of a pixel. The delta object would be a triple (X, Y, old_color). When you change (X, Y) to new color you push the delta triple incl. the old color on the stack. Later when you undo you pop the delta object and write the old color back to the screen. Setting every pixel black on a 1000x1000 canvas would create 1 million delta objects. In practice of course graphics programs do it in a more optimized fashion.Doering
Instead of using a stack, you could also use a queue with a "now" pointer. This allows both undo and redo functionality to be easily implemented by moving backwards and forward in the queue (i.e. undo backs up one object in the queue and redo steps forward and redoes the action).Planetesimal
O
0

Take a look at Memento Design Pattern.

Overmatter answered 31/3, 2009 at 13:35 Comment(0)
F
0

Here is what worked for me in sqlite3

BEGIN;
-- enter your INSERT, UPDATE or DELETE command
-- if you want to keep it then run command below
COMMIT;
-- to undo - run command below
ROLLBACK;

Source SQLite Transactions (Begin, Commit, Rollback)

Flowerlike answered 2/2, 2020 at 19:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.