The data expiration control is one of the main problem with stateless and multi access applications. The web service should check if data on the back end was changed meanwhile. How to do it? There are many ways to check if data was changed. The most trivial one seems to be lock record while reading. Then unlock if update operation is performed. But this is against stateless rule. You never know if the update operation will come and will be operated by the same job. It may happen that update operation will never be sent from client. What to do then with locked records? In aperio we introduced mchanism which helps You to calculate record state hash code. Based on entire record from database you can calculate hash code. There is possbilitity to send to the client hash code of record together with data while reading. Then the update procedure must send saved hash code back to the manager program. Manager program once again calculates current hash code of record and compare it to this one which was received from client. If there are no changes then update is allowed. If hash codes are different then error message is send back to the client.
There is procedure which calculates hash code based on any data. You need to provide addres of data and size of data in bytes.
xxData = 'Any text, for example Hello World!';
xxHashCode = generateHashCode(%ADDR(xxData): %SIZE(xxData));
Here is example how the “get” method/program may be created:
FFILE01 UF A E K DISK
D gF01 E DS EXTNAME(FILE01)
D gKeyFile01 DS likerec(F01:*key)
D l_hash S 32A
gKeyFile01.FLD01 = 'ABC';
chain(n) %kds(gKeyFile01) FILE01;
if %found(FILE01);
//Calculate hash code for record
l_hash = generateHashCode(%ADDR(gF01): %LEN(gF01));
respAddElement('data');
respAddStringField('data': 'field01' :FLD01);
respAddStringField('data': 'field02' :FLD02);
respAddNumericField('data': 'field03' :FLD03);
respAddStringField('data': 'hashCode' :l_hash);
endif;
Here is example how the “update” method/program may be created:
FFILE01 UF A E K DISK
D gF01 E DS EXTNAME(FILE01)
D gKeyFile01 DS likerec(F01:*key)
D l_hashCurrent S 32A
D l_hashOld S 32A
if reqExist('params' :'hashCode');
l_hashOld = reqGetValue('params':'hashCode');
else;
return API_PARAMS_ERR;
endif;
gKeyFile01.FLD01 = 'ABC';
chain %kds(gKeyFile01) FILE01;
if %found(FILE01);
//Calculate hash code for record
l_hashCurrent = generateHashCode(%ADDR(gF01): %LEN(gF01));
//Validate if current hash code of record is equal
//to received one. If so, then update
if l_hashOld = l_hashCurrent;
//... continue update
//...
update F01;
else;
unlock FILE01;
respAddMessage('ERROR':
'E000001':
'HashCode':
'Hash code has expired');
return API_APPLICATION_ERR;
endif;