Partner400 Logo
    Source Code for Open Access Handler Template
   

These are the Open Access handler and test program that are described in the IBM i Extra magazine article "List Handling With Open Access" which you can find here: http://www.ibmsystemsmag.com/ibmi/developer/rpg/oa_lists/

[an error occurred while processing this directive]

This is the handler program LISTHANDLR. The test programs LISTHANDT1 and LISTHANDT2 can be found further down the page.
	

// This program demonstrates the handling of list data via
// CHAIN, SETLL, and READ.
// Extension to handle READE and other stuff should be pretty easy

H DftActGrp(*No) Option(*SrcStmt: *NoDebugIO)

// User Data - normally in a copy source - modify as required
D userData_T ds
D userParm 10a

// Standard IBM supplied Open Access definitions
/Copy QRNOPENACC

// Copy RPG status codes
/Copy MonStatCds

// Protos for program and local procedures - not needed v7+
D OpenFile Pr

D CloseFile Pr

D ListHandler Pr ExtPgm('LISTHNDLR')
D info likeds(QrnOpenAccess_T)

// Input buffer definition for the ARRAYFILE
d inputBuffer e ds Based(info.inputBuffer)
d ExtName(ARRAYFILE)

// Key definition
d key e ds Based(info.key) Qualified
d ExtName(ARRAYFILE:*KEY)

// State info - records the current position in the "file"
d stateInfo DS Based(info.stateInfo) Qualified
D currentPos 5i 0

// Program interface - our old friend the OA info structure
D ListHandler PI
D info likeds(QrnOpenAccess_T)

// This is the list that this demo handler will process - it could be
// anything and it could be anywhere. For example a web service
// might return a list of orders for a customer. It could be a list
// of spool files from a spool API. etc. etc.
(E) D listKeys DS
D keyData 60a Inz('A001+
D B002+
D B099+
D B199+
D C200+
D C399+
D D001+
D E002+
D F099+
D G199+
D J200+
D J399+
D P001+
D R399+
D T001')
D keyArray 4a Dim(15) Overlay(keyData) Ascend

D tempKey s 4a

/Free

Select;

When (info.rpgOperation = QrnOperation_SETLL);
doSETLL();

When (info.rpgOperation = QrnOperation_CHAIN);
doCHAIN();

When (info.rpgOperation = QrnOperation_READ);
doREAD();

When (info.rpgOperation = QrnOperation_OPEN);
OpenFile();

When (info.rpgOperation = QrnOperation_CLOSE);
CloseFile();

Other; // We don't know how to do this operation
Dsply ('Unsupported function ' + %Char(info.rpgOperation)
+ ' on queue ' + info.externalFile.name );
info.rpgStatus = errIO;

EndSl;

// If end of file has been set then set current position to high value
If info.eof;
stateInfo.currentPos = *HiVal;
EndIf;

Return;
/End-Free

// Basic logic for Open function
P OpenFile B
D PI

/Free
// If no state info area yet allocate now and initialize
(F) If info.stateInfo = *null;
info.stateInfo = %Alloc( %Size(stateInfo));
Clear stateInfo;
EndIf;

// Here is where you would load list data in from an external source
// We're just going to sort the data already in the array
(G) SortA keyArray;

(H) stateInfo.currentPos = 1; // Effectively set to beginning of "file"

Return;

/End-Free

P OpenFile E


P CloseFile B
D PI

/Free

// Release storage holding state information and set pointer to null
Dealloc info.stateInfo;
info.stateInfo = *null;
info.rpgStatus = stsOK;

/End-Free

P CloseFile E


P doSETLL B
D PI

d posn s 5i 0

/Free
tempKey = key.data; // For debugging only

// Lookup given key and set posn.
(I) posn = %LookUpGE( key.data: keyArray );

// If we have found a match, set %Found flag and clear %EOF
// Current cursor posn and EOF are left unchanged if no new
// position established
// %Equal will also be set if key at posn is an exact match

(J) If ( posn > 0 );
stateInfo.currentPos = posn;
info.found = *On;
info.eof = *Off;
info.equal = ( key.data = keyArray(posn) ); // Set %Equal on match
EndIf;

/End-Free

P doSETLL E

// CHAIN routine
P doCHAIN B
D PI

d posn s 5i 0

/Free

tempKey = key.data; // For debugging

// Lookup given key and return appropriate data
posn = %LookUp( key.data: keyArray );

If posn > 0;
info.found = *On; // Set on %Found
info.eof = *Off; // and clear %EOF
stateInfo.currentPos = posn;
inputBuffer.seqNo = stateInfo.currentPos;
inputBuffer.data = keyArray(stateInfo.currentPos);
stateInfo.currentPos = posn + 1; // Set to next position
Else;
info.found = *Off; // Set off %Found
EndIf;

/End-Free

P doCHAIN E

// Read routine. Only READ supported currently
P doREAD B
D PI

/Free

// Obtain next entry from array and return data or set eof etc.

If stateInfo.currentPos <= %elem(keyArray);
// Return data at current position
inputBuffer.seqNo = stateInfo.currentPos;
inputBuffer.data = keyArray(stateInfo.currentPos);
// And increment to next position
stateInfo.currentPos += 1;
Else;
info.eof = *On; // Set EOF if at end of list
EndIf;

/End-Free

P doREAD E


These are the test programs TESTLISTH1 and TESTLISTH2.

TESTLISTH1

       // This program demonstrates the CHAIN and READ capabilities of
// the OA list handler
(A) FArrayFile IF E K DISK Handler('LISTHANDLR')

d key s Like(Data)

D exit c 'exit'

/Free

DoU key = exit;

Dsply ('Enter record key: ("exit" to end)') ' ' key;

If key = exit;
Leave;
EndIf;

(B) Chain key ArrayFile; // Chain using key entered

// Report sucess/failure
(C) If %Found(ArrayFile);
Dsply ('Key ' + key + ' found at sequence ' + %Char(seqno));
Else;
Dsply ('Unable to locate ' + key);
EndIf;

// Read and display the next record regardless of the CHAIN's sucess
(D) Read ArrayFile;

If %Eof(ArrayFile);
Dsply ('EOF reached');
Else;
Dsply ('Key ' + data + ' found at position ' + %Char(seqno));
EndIf;

EndDo;

*InLr = *On;


TESTLISTH2

// Program to test the SeTLL and READ capabilities of the
// OA list handler

FArrayFile IF E K DISK Handler('LISTHANDLR')

d key s Like(data)

D exit c 'exit'

/Free

DoU key = exit;

Dsply ('Enter record key: ("exit" to end)') ' ' key;

If key = exit;
Leave;
EndIf;

SetLL key ArrayFile;

// Report on status of SETLL operation
If %Equal(ArrayFile);
Dsply ('Positioned at ' + key );
ElseIf %Found(ArrayFile);
Dsply ('Exact match not found for ' + key);
Else;
Dsply ('Unable to position to ' + key);
EndIf;

// If we were able to position the "file" then loop until EOF
If %Equal(ArrayFile) or %Found(ArrayFile);

DoU %Eof(ArrayFile);
Read ArrayFile;
If not %Eof(ArrayFile);
Dsply ('Next record has key ' + data +
' location ' + %Char(seqno));
Else;
Dsply ('EOF reached');
EndIf;
EndDo;

EndIf;

EndDo;

*InLr = *On;





     
Return to Home Page  

Want more information?
Got a question or comment about the site?
Please feel free to Contact Us at any time.}