Monday, February 25, 2008

Revision Control for Rows

Revision Control deals with managing multiple revisions of an entity. The core functionality in any Revision Control system is to ensure that the previous version is not lost. Revision Control is a vast topic that merits hours of study & practice.

I definitely don't have the breadth of knowledge or experience to comment on various "must-have" features, etc. However, I did encounter an interesting scenario where I put Revision Control to practice for information stored in rows of a Database Table.

We can achieve Revision Control for rows in a Database Table in a simple way - with two columns. We can use one column to store the Row version and another to "flag" the row that contains the latest version.

I am using an Oracle XE Database & Oracle SQL Developer to model the tables, fashion out the queries, etc. You could do the same with any other Database & your favorite tools.

Here, I consider the example of an Item "on display" at a shop. The Product is available in multiple version ( different colors ), but only one "version" of the product is currently on display ( the item ).

First, I'll model the database table. I have made a few assumptions to arrive at this model :-

Assumption # 1 :- All the rows are linked by a common identifier ( in my case, the Product ID ).
Assumption # 2 :- At any given point of time, only one version of the product is "active".
Assumption # 3 :- Each "version" is saved into the database. Any "undo" will simply revert back to the previous saved version.
Assumption # 4 :- Each "undo" or "redo" is saved into the database as the current version.

Here's a table that shows this design :-

CREATE TABLE ITEM
(
ITEM_ID NUMBER PRIMARY KEY,
ITEM_PRODUCT_ID NUMBER,
ITEM_DESCRIPTION VARCHAR2(100),
ITEM_COLOR VARCHAR2(10),
ITEM_VERSION NUMBER,
ITEM_CURRENT_VERSION VARCHAR2(1) CONSTRAINT check_ver_flag CHECK(ITEM_CURRENT_VERSION IN ('Y','N'))
);


Here's the data that I stuffed into the table :-

INSERT INTO ITEM VALUES (1,566,'Smiley Dolls','Red',1,'N');
INSERT INTO ITEM VALUES (2,566,'Smiley Dolls','Blue!',2,'N');
INSERT INTO ITEM VALUES (3,566,'Smiley Dolls','Yellow',3,'Y');
INSERT INTO ITEM VALUES (4,566,'Smiley Dolls','Cyan',4,'N');

COMMIT;


Now, to dish out the queries...

Which is the current version of the Product ?

SELECT ITEM_DESCRIPTION, ITEM_COLOR FROM ITEM WHERE ITEM_CURRENT_VERSION = 'Y';

ITEM_DESCRIPTION ITEM_COLOR
------------------- ----------
Smiley Dolls Yellow

1 rows selected


Can we "undo" the current version & revert to the previous saved version ?

SELECT a.ITEM_DESCRIPTION, a.ITEM_COLOR FROM ITEM A, ITEM B
WHERE A.ITEM_VERSION = B.ITEM_VERSION-1 AND B.ITEM_CURRENT_VERSION = 'Y'


ITEM_DESCRIPTION ITEM_COLOR
----------
Smiley Dolls Blue!

1 rows selected


( After this, we set the current version flag to "Y" )

Revision Control can be achieved in this simple manner.

No comments: