Re: [sqlite] Undo logs and transactions

2008-05-13 Thread David Barrett
Yes, I completely agree.  But a single "undoable event" generates 
multiple changes to the database (which might as well be done inside a 
single transaction).  Thus one click on Undo results in multiple changes 
to undo the event (ie, undoing the entire event's transaction).  This 
implies that somehow the undo log either:

- Tags multiple rows in the undo log as comprising a single event, or
- Accumulates multiple queries into a single row in the undo log

I really liked the elegance of using triggers to automatically create 
the undo log, but I don't see how to accomplish either of the above 
strategies (tagging a group of undo rows, or concatenating multiple 
undos into a single row) in that design without some manual legwork.

So my question was whether there is some "COMMIT_COUNT()" SQL function 
or constant that represents "the number of committed transactions on 
this database", as then I could just stick that in the trigger query and 
insert it along with the undo query into the undo log as follows:

CREATE TEMP TRIGGER _ex1_it AFTER INSERT ON ex1 BEGIN
INSERT INTO undolog VALUES(NULL,COMMIT_COUNT(),'DELETE FROM ex1 WHERE 
rowid='||new.rowid);
END;

Then multiple INSERTs in a single transaction would generate multiple 
DELETEs in the undolog, all tagged with the same commit count.  Later, I 
could look up the set of queries necessary to undo that transaction with:

SELECT sql FROM undolog WHERE commitcount=XXX;

The upshot is I could roll back one transaction at a time, all the way 
back to the beginning (or as far as the undo log goes).

But lacking a COMMIT_COUNT() function, I might instead just create a 
simple table:

CREATE TABLE commitcount(num)

And then increment that at the start of each transaction:

UPDATE commitcount SET num=(SELECT num FROM commitcount)+1;

And then my trigger could be something like:

CREATE TEMP TRIGGER _ex1_it AFTER INSERT ON ex1 BEGIN
INSERT INTO undolog VALUES(NULL,(SELECT num FROM commitcount),'DELETE 
FROM ex1 WHERE rowid='||new.rowid);
END;

This'll do the same thing, but requires a subquery, an extra table, and 
manual incrementing of the commit count.  Works, but is yucky.

Another way might be to create a table that just keeps track of which 
range in the undolog corresponds to which distinct undoable event (aka 
transaction)... Perhaps a bit cleaner, but still not great.

Anyway, I was just curious if the COMMIT_COUNT() function existed, 
because then it'd be really clean and easy.  But it sounds it doesn't, 
and that's what I wanted to know.  Thanks!

-david

D. Richard Hipp wrote:
> On May 13, 2008, at 6:21 PM, David Barrett wrote:
> 
>> True, but even an application would need to "undo" in transactions,  
>> I'd
>> think.  Like, if a user drags a widget from column A to B, it  
>> generates
>> an INSERT in one column and a DELETE in another.  Pressing Undo once
>> would leave it in both columns, which is probably unexpected.
>>
> 
> And undo/redo mechanism typically groups actions together by user  
> input event.  The application is typically event driven.  It sits idle  
> waiting for a user event, such as a mouse click.  That event might  
> trigger a cascade of related events, some of which involve database  
> changes.  All database changes associated with that one event are  
> undone together.  You know that you have reached the end of your event  
> cascade when the event loop goes idle again.
> 
> For processing gestures (drags, and other inputs that involve multiple  
> events spread out over time) you acquire a lock or a "grab" at the  
> beginning of the gesture, hold it throughout the gesture, then release  
> it when the gesture completes.  You do not finish the undo package  
> until the end of the gesture.  So the complete rule for when you stop  
> one undoable entry and start a new one is: you are idle (no pending  
> events) and you are not holding a grab.
> 
> D. Richard Hipp
> [EMAIL PROTECTED]
> 
> 
> 
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Undo logs and transactions

2008-05-13 Thread David Barrett
True, but even an application would need to "undo" in transactions, I'd 
think.  Like, if a user drags a widget from column A to B, it generates 
an INSERT in one column and a DELETE in another.  Pressing Undo once 
would leave it in both columns, which is probably unexpected.

Anyway, I was more thinking of a "transaction count" sort of variable, 
indicating how many total transactions have been committed to the 
database.  Just something to group undo log entries by transaction 
without maintaining a manual transaction identifier.

Thanks for considering it!

-david

Ken wrote:
> the Undo/Redo mechanism described is not really for transactions but rather a 
> "Button" within an application. So that the user can undo/redo changes.
> 
> Only one transaction can be active at a time. So to the best of my knowledge 
> there is no "transaction number" as there can be only 1. Now you may go ahead 
> and implement "pseudo transactions" and implement your own transaction 
> number.  etc...
> 
> HTH,
> Ken
> 
> 
> David Barrett <[EMAIL PROTECTED]> wrote: What's the best way to group undo 
> log entries by transaction?  Is there 
> a function that returns the current transaction number?  Or what's the 
> best way to set a global variable that is inserted into the undo log by 
> the trigger?
> 
> As background, the wiki has a great page on undo/redo:
> 
>  http://www.sqlite.org/cvstrac/wiki?p=UndoRedo
> 
> But unless I misunderstand, it seems that a single transaction will 
> create multiple entries in the log.  For example, a transaction 
> containing both an insert and a delete will generate two entries in the 
> undo log.  Therefore, to undo that transaction, I need to atomically 
> commit the "undo" of both the insert and delete in a single transaction.
> 
> That's fine, but the log created by the example doesn't seem to indicate 
> which group of undo rows correspond to a single transaction.  Indeed, 
> the word "transaction" doesn't even appear in the page.
> 
> Now, digging through the archives I see reference to a "transaction 
> number" here:
> 
> http://www.mail-archive.com/sqlite-users@sqlite.org/msg23962.html
> 
> Is there any explicit way to get the current transaction number?  I was 
> hoping to see some "transaction_number()" function here, but I don't:
> 
>  http://www.sqlite.org/lang_corefunc.html
> 
> If such a function did exist, then I could just update the triggers to 
> insert that along with the corresponding SQL.
> 
> Lacking that, what's the best way to manually to set some kind of global 
> variable at the start of each transaction?  One way is to maintain a 
> separate table with a single cell containing the latest transaction 
> number (which I manually increment at the start of each transaction) and 
> then just SELECT that in the trigger sub-query, but that seems yucky. 
> Is there an easier way I'm missing?
> 
> Thanks!
> 
> -david
> 
> 
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
> 
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Undo logs and transactions

2008-05-13 Thread Ken
the Undo/Redo mechanism described is not really for transactions but rather a 
"Button" within an application. So that the user can undo/redo changes.

Only one transaction can be active at a time. So to the best of my knowledge 
there is no "transaction number" as there can be only 1. Now you may go ahead 
and implement "pseudo transactions" and implement your own transaction number.  
etc...

HTH,
Ken


David Barrett <[EMAIL PROTECTED]> wrote: What's the best way to group undo log 
entries by transaction?  Is there 
a function that returns the current transaction number?  Or what's the 
best way to set a global variable that is inserted into the undo log by 
the trigger?

As background, the wiki has a great page on undo/redo:

 http://www.sqlite.org/cvstrac/wiki?p=UndoRedo

But unless I misunderstand, it seems that a single transaction will 
create multiple entries in the log.  For example, a transaction 
containing both an insert and a delete will generate two entries in the 
undo log.  Therefore, to undo that transaction, I need to atomically 
commit the "undo" of both the insert and delete in a single transaction.

That's fine, but the log created by the example doesn't seem to indicate 
which group of undo rows correspond to a single transaction.  Indeed, 
the word "transaction" doesn't even appear in the page.

Now, digging through the archives I see reference to a "transaction 
number" here:

http://www.mail-archive.com/sqlite-users@sqlite.org/msg23962.html

Is there any explicit way to get the current transaction number?  I was 
hoping to see some "transaction_number()" function here, but I don't:

 http://www.sqlite.org/lang_corefunc.html

If such a function did exist, then I could just update the triggers to 
insert that along with the corresponding SQL.

Lacking that, what's the best way to manually to set some kind of global 
variable at the start of each transaction?  One way is to maintain a 
separate table with a single cell containing the latest transaction 
number (which I manually increment at the start of each transaction) and 
then just SELECT that in the trigger sub-query, but that seems yucky. 
Is there an easier way I'm missing?

Thanks!

-david


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users