On 17 July 2014 21:43, Tristan Van Berkom <[email protected]> wrote:
>
> Hi all,
>
> We've been pondering how to keep history of structured records without
> storing the entirety of the structured record for each new revision, we
> have some ideas on how to achieve this but I wanted to consult this list
> in case we have overlooked some other strategies, and also just to see
> if our proposed solution to the problem is sound.
We faced similar requirements when designing a financial application and
after some experimentation we settled on an approach very similar to what
you propose. There are quite a few tricky details, one relates to deletions
(which is not mentioned in your email so perhaps it is not relevant) and an
other relates to the actual workflow; how the main application interacts with
the database. Here is a detailed example that highlights some of the tricky
parts (long -- sorry list):
----------
TransactionId is a unique id corresponding to the actual database transaction
which may or may not be useful to you
EntryId corresponds to your revision number and is (strictly)
monotically increasing
to avoid having to rely on timestamps for temporal ordering.
GroupEntryId is the unique id of the event which remains constant throughout
the life time of the event
EntryType is how we deal with the workflow issue; when working with an event
record the main app sets the EntryType to 'New' for new records,
'Amend' when amending an existing record and 'Delete' for deleting an existing
record. The main app interacts with the Event table by issuing only inserts
and issues queries on the EventCurrent table which is automatically maintained
by the triggers below. Manual (ie sql console) maintenance of the
Event table is also
handled by triggers.
create table Event (
_id integer primary key autoincrement,
TimeStamp timestamp not null,
TransactionId text not null COLLATE NOCASE,
EntryId text unique COLLATE NOCASE,
GroupEntryId text not null COLLATE NOCASE,
EntryType text COLLATE NOCASE,
EventProperty1 text,
EventProperty2 text
)
create table EventCurrent (
_id integer primary key autoincrement,
TimeStamp timestamp not null,
TransactionId text not null COLLATE NOCASE,
EntryId text unique COLLATE NOCASE,
GroupEntryId text not null COLLATE NOCASE,
EntryType text COLLATE NOCASE,
EventProperty1 text,
EventProperty2 text
)
create trigger trg_Event_update after update on Event for each row
begin
update EventCurrent set
_id = NEW._id,
TimeStamp = NEW.TimeStamp,
TransactionId = NEW.TransactionId,
EntryId = NEW.EntryId,
GroupEntryId = NEW.GroupEntryId,
EntryType = NEW.EntryType,
EventProperty1 = NEW.EventProperty1,
EventProperty2 = NEW.EventProperty2
where EventCurrent._id = NEW._id;
end
create trigger trg_Event_delete after delete on Event for each row
begin
delete from EventCurrent
where EventCurrent.EntryId = OLD.EntryId;
replace into EventCurrent
select * from Event where GroupEntryId = OLD.GroupEntryId and
EntryId = (select max(EntryId) from Event where
GroupEntryId = OLD.GroupEntryId);
delete from EventCurrent
where EventCurrent.EntryId is null;
end
create trigger trg_Event_insert_amend before insert on Event for each row
when NEW.EntryType is not null and NEW.EntryType = 'Amend'
begin
delete from EventCurrent
where EventCurrent.GroupEntryId = NEW.GroupEntryId;
end
create trigger trg_Event_insert_delete after insert on Event for each row
when NEW.EntryType is not null and NEW.EntryType = 'Delete'
begin
delete from EventCurrent
where EventCurrent.GroupEntryId = NEW.GroupEntryId;
end
create trigger trg_Event_insert_new after insert on Event for each row
when NEW.EntryType is not null and (NEW.EntryType = 'New' or
NEW.EntryType = 'Amend' or NEW.EntryType = '')
begin
insert into EventCurrent values (
NEW._id,
NEW.TimeStamp,
NEW.TransactionId,
NEW.EntryId,
NEW.GroupEntryId,
NEW.EntryType,
NEW.EventProperty1,
NEW.EventProperty2
);
end
Cheers
--
Pavlos Christoforou
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users