RPG Bean
A service program to set and get data.
IO Service Program
In Java, a class that provides methods to set and get the values of the properties, known as getter and setter methods, is generally called a bean.This service program example functions as a file I/O manager. I borrowed the idea from Aaron Bartell, who once coined the term "green Bean". Like a Java Bean, procedures within the service program manage operations on the data--setters and getter procedures. This technique effectively separates the data from the presentation layer. Applications using the data do not have to include the table rows or columns. Instead, a procedure call returns data, or pushes data to the table.
H/TITLE ** EXP010RM I/O Module ** H DEBUG(*YES) h nomain **************************************************************** * PROGRAM NAME - SC0950RM * * * * FUNCTION - This is a service program designed to serve * * as a file I/O manager for the SC objects * * file * * * * PROGRAMMER - STEVE CROY 99/99/9999 iSoftwerks, Inc * **************************************************************** **************************************************************** * Compile instructions * *CRTMOD *SQLRPGLE * *DLYPRP *YES * *DBGVIEW *SOURCE * **************************************************************** **************************************************************** * MODIFICATION LOG * * * * DATE PROGRAMMER DESCRIPTION * * * **************************************************************** *--- * Global Variables *--- D OBJECT E DS extname(SCOBJSPF) prefix(n_) D PGMDS ESDS EXTNAME(SCPSTSPF) D sql S 32767a varying D fileName S 20a varying inz( 'SCOBJSPF') D SQLSTTOK C '00000' D SQLEOF c const('02000') *--- * Procedure copybooks *--- /copy qrpglesrc,sc0000_PR *--- * Get record and populate DS *--- p RetrieveObject B EXPORT D RetrieveObject PI N D p_OBJ 10a CONST D p_TYP 10a CONST d isFound s n inz(*off) ClearObject() ; EXEC SQL Set Option Commit = *None ; EXEC SQL SELECT * into :OBJECT from SCOBJSPF WHERE exobnm= :p_OBJ AND exobtp = :p_TYP ; IF SQLSTT = SQLSTTOK ; isFound = *on ; ENDIF ; RETURN isFound ; p RetrieveObject e p ClearObject B export d ClearObject PI clear OBJECT ; return ; p ClearObject e p SetObjectCursor... p b export d SetObjectCursor... d pi n d orderBy 256a CONST OPTIONS(*NOPASS) d selectOnly 256a CONST OPTIONS(*NOPASS) d isFound s n inz(*off) d errorOccurred s n inz(*off) d dftSelect s 30a inz('select * from SCOBJSPF') d dftorder s 30a inz('order by EXOBNM,EXOBTP') d genericString s 10a d orderString s 256a d SelectString s 256a d qt s 1a inz('''') d QRYstring s 500a d len s 3S 0 IF %parms >= 1 and orderby > *blanks; OrderString = %trim(orderBy); ELSE; OrderString = dftorder; ENDIF; IF %parms > 1 and SelectOnly > *blanks; SelectString = %trim(SelectOnly); ELSE; SelectString = dftSelect; ENDIF; QRYstring = %trim(SelectString) + ' ' + %trim(OrderString); EXEC SQL PREPARE selStmt FROM :QRYstring; EXEC SQL DECLARE ObjectCursor SCROLL CURSOR FOR selStmt; EXEC SQL OPEN ObjectCursor; IF SQLSTT = SQLSTTOK ; ErrorOccurred = *off ; ELSE ; ErrorOccurred = *ON ; ENDIF ; RETURN ErrorOccurred ; p SetObjectCursor... p e p NextObject b export d NextObject pi n d isFound s n inz(*off) d errorOccurred s n inz(*off) EXEC SQL FETCH NEXT FROM ObjectCursor INTO :OBJECT; IF SQLSTT = SQLEOF; ISFOUND = *OFF ; ELSE; ISFOUND = *ON; ENDIF; RETURN ISFOUND; P NextObject e p CloseObjectCursor... p b export d CloseObjectCursor... d pi n d isFound s n inz(*off) d errorOccurred s n inz(*off) EXEC SQL CLOSE ObjectCursor; IF SQLSTT = SQLSTTOK; ErrorOccurred = *OFF; ELSE; ErrorOccurred = *ON; ENDIF; RETURN ErrorOccurred; p CloseObjectCursor... p e P GetObjectData b export D GetObjectData pi 197a RETURN OBJECT; P GetObjectData e P InsertObject b export D InsertObject pi n D isInserted s n D NextSequence s 7 0 SELECT; WHEN n_exobtp= 'PF'; n_excats = 50; WHEN n_exobtp= 'LF'; n_excats = 100; WHEN n_exobtp= 'DTAARA'; n_excats = 150; WHEN n_exobtp= 'DSPF'; n_excats = 200; WHEN n_exobtp= 'DSPF36'; n_excats = 205; WHEN n_exobtp= 'PRTF'; n_excats = 250; WHEN n_exobtp= 'MOD'; n_excats = 300; WHEN n_exobtp= 'SVC'; n_excats = 350; WHEN n_exobtp= 'MNUCMD'; n_excats = 450; WHEN n_exobtp= 'CHECK'; n_excats = 800; WHEN n_exobtp= 'EVENT'; n_excats = 900; OTHER; n_excats = 500; ENDSL; EXEC SQL select max(excseq) into :NextSequence from SCOBJSPF where excats = :n_excats; n_excseq = NextSequence + 1; IF n_exombr = *blanks; n_exombr = n_exobnm; ENDIF; n_exaddt = %dec(%char(%date():*iso0):8:0); n_exadtm = %dec(%char(%time():*hms0):6:0); n_EXADUS = user; n_EXproc = 'N'; IF n_exobtp = 'EVENT' or n_exobtp = 'CHECK'; n_EXOBSR = '*NONE' ; n_EXOMBR = '*NONE' ; n_EXOBSL = '*NONE' ; n_EXOBLB = '*NONE' ; n_EXCOMP = 'N' ; n_EXMOVO = 'N' ; n_EXMOVS = 'N' ; n_EXACMD = 'N' ; ENDIF ; exec sql insert into SCOBJSPF ( excats , excseq , exobnm , exobtp , EXDESC , EXOBSR , EXOMBR , EXOBSL , EXCOMP , EXMOVO , EXMOVS , EXACMD , EXOBLB , EXADDT , EXADTM , EXADUS , EXCHDT , EXCHTM , EXCHUS , EXPROC , EXPRDT , EXPRTM , exprus ) values ( :n_excats , :n_excseq , :n_exobnm , :n_exobtp , :n_EXDESC , :n_EXOBSR , :n_EXOMBR , :n_EXOBSL , :n_EXCOMP , :n_EXMOVO , :n_EXMOVS , :n_EXACMD , :n_EXOBLB , :n_exaddt , :n_EXADTM , :n_EXADUS , :n_EXCHDT , :n_EXCHTM , :n_EXCHUS , :n_EXPROC , :n_EXPRDT , :n_EXPRTM , :n_exprus ); IF SQLSTT = SQLSTTOK ; isInserted = *on ; ENDIF ; RETURN isInserted ; P InsertObject e P UpdateObject b export D UpdateObject pi n D isUpdated s n n_exchdt = %dec(%char(%date():*iso0):8:0); n_exchtm = %dec(%char(%time():*hms0):6:0); n_EXchUS = user; EXEC SQL UPDATE SCOBJSPF Set excats = :n_excats , excseq = :n_excseq , exobnm = :n_exobnm , exobtp = :n_exobtp , EXDESC = :n_EXDESC , EXOBSR = :n_EXOBSR , EXOMBR = :n_EXOMBR , EXOBSL = :n_EXOBSL , EXCOMP = :n_EXCOMP , EXMOVO = :n_EXMOVO , EXMOVS = :n_EXMOVS , EXACMD = :n_EXACMD , EXOBLB = :n_EXOBLB , EXADDT = :n_exaddt , EXADTM = :n_EXADTM , EXADUS = :n_EXADUS , EXCHDT = :n_EXCHDT , EXCHTM = :n_EXCHTM , EXCHUS = :n_EXCHUS , EXPROC = :n_EXPROC , EXPRDT = :n_EXPRDT , EXPRTM = :n_EXPRTM , exprus = :n_exprus WHERE exobnm = :n_exobnm and exobtp = :n_exobtp; IF SQLSTT = SQLSTTOK ; isUpdated = *on ; ENDIF ; RETURN isUpdated ; P UpdateObject e p DeleteObject b export d DeleteObject pi n d isDeleted s n inz(*off) d errorOccurred s n inz(*off) EXEC SQL DELETE FROM SCOBJSPF WHERE exobnm = :n_exobnm and exobtp = :n_exobtp; IF SQLSTT = SQLSTTOK ; isDeleted = *on ; ENDIF ; RETURN isDeleted ; p DeleteObject e p SetObjCat b export d SetObjCat pi d p_Cat 3s 0 n_excats = p_Cat; RETURN; p SetObjCat e p GetObjCat b export d GetObjCat pi 3S 0 RETURN n_excats; p GetObjCat e p SetObjSeq b export d SetObjSeq pi d p_Seq 7s 0 n_excseq = p_seq; RETURN; p SetObjSeq e p GetObjSeq b export d GetObjSeq pi 7S 0 RETURN n_excseq; p GetObjSeq e p SetObjNam b export d SetObjNam pi d p_Nam 10a n_exobnm = p_nam; RETURN; p SetObjNam e p GetObjNam b export d GetObjNam pi 10a RETURN n_exobnm; p GetObjNam e p SetObjTyp b export d SetObjTyp pi d p_Typ 10a n_exobtp = p_typ; RETURN; p SetObjTyp e p GetObjTyp b export d GetObjTyp pi 10a RETURN n_exobtp; p GetObjTyp e p SetObjDsc b export d SetObjDsc pi d p_Dsc 50a n_exdesc = p_dsc; RETURN; p SetObjDsc e p GetObjDsc b export d GetObjDsc pi 50a RETURN n_exdesc; p GetObjDsc e p SetObjSrc b export d SetObjSrc pi d p_src 10a n_exobsr = p_src; RETURN; p SetObjSrc e p GetObjSrc b export d GetObjSrc pi 10a RETURN n_exobsr; p GetObjSrc e p SetObjMbr b export d SetObjMbr pi d p_mbr 10a IF p_mbr = *blanks; n_exombr = n_exobnm; ELSE; n_exombr = p_mbr; ENDIF; RETURN; p SetObjMbr e p GetObjMbr b export d GetObjMbr pi 10a RETURN n_exombr; p GetObjMbr e p SetSrcLib b export d SetSrcLib pi d p_lib 10a n_exobsl = p_lib; RETURN; p SetSrcLib e p GetSrcLib b export d GetSrcLib pi 10a RETURN n_exobsl; p GetSrcLib e p CompileObject b export d CompileObject pi d YNFlag 1 CONST n_excomp = YNFlag; RETURN; p CompileObject e p MoveObject b export d MoveObject pi d YNFlag 1 CONST n_exmovo = YNFlag; RETURN; p MoveObject e p MoveSource b export d MoveSource pi d YNFlag 1 CONST n_exmovs = YNFlag; RETURN; p MoveSource e p AlternateCmd b export d AlternateCmd pi d YNFlag 1 CONST n_exacmd = YNFlag; RETURN; p AlternateCmd e p SetObjLib b export d SetObjLib pi d p_lib 10a n_exoblb = p_lib; RETURN; p SetObjLib e p GetObjLib b export d GetObjLib pi 10a RETURN n_exoblb; p GetObjLib e P ObjectProcess b export D ObjectProcess pi n D isProcessed s n n_exproc = 'Y'; n_exprdt = %dec(%char(%date():*iso0):8:0); n_exprtm = %dec(%char(%time():*hms0):6:0); n_exprus = user; isProcessed = UpdateObject(); RETURN isProcessed ; P ObjectProcess e P ResetProcess b export D ResetProcess pi n D isProcessed s n n_exproc = 'N'; isProcessed = UpdateObject(); RETURN isProcessed ; P ResetProcess e P ProcException b export D ProcException pi n D isProcessed s n n_exproc = 'E'; n_exprdt = %dec(%char(%date():*iso0):8:0); n_exprtm = %dec(%char(%time():*hms0):6:0); n_exprus = user; isProcessed = UpdateObject(); RETURN isProcessed ; P ProcException e * P ObjectObsolete b export D ObjectObsolete pi n D isProcessed s n n_exproc = 'O'; n_exprdt = %dec(%char(%date():*iso0):8:0); n_exprtm = %dec(%char(%time():*hms0):6:0); n_exprus = user; isProcessed = UpdateObject(); RETURN isProcessed ; P ObjectObsolete e P ObjectExpanded b export D ObjectExpanded pi n D isProcessed s n n_exproc = 'X'; n_exprdt = %dec(%char(%date():*iso0):8:0); n_exprtm = %dec(%char(%time():*hms0):6:0); n_exprus = user; isProcessed = UpdateObject(); RETURN isProcessed ; P ObjectExpanded e *** End of module source ***
The service program can be used by any bound process to request (get) or put (set) data to the object table (SCOBJSPF). The side bar has snippetts from two program that access the (SC0950SV) service program. SC0320RP is a simple list presentation that loads a subfile by requesting a row from the service program. The second program, SC0335RP mentioned is an interactive maintenace program that gets and sets table data via the service program.
Binding Note
The module SC0950RM should be created as a module, then created as a service program. I recommend binder source in most instances, however, there is no need for a binder source, simply specify *ALL for export. CRTSRVPGM SRVPGM(SCROY/SC0950SV) MODULE(SC0950RM) EXPORT(*ALL) TEXT('Softcode object services')
Database
The physical file is keyed by the object and type columns. There are fields commented as audit fields. There are no external procedures to set the values of these fields. The values for the create date and time and the change date and time are established by the service program. This is to ensure they will be populated when the record is created and when it is changed--and will only happen within the I/O manager, and not by applications that are bound to the service program.
A**************************************************************** A* PHYSICAL FILE- SCOBJSPF * A* * A* FUNCTION - This is object list for the SOFTCODE system * A* * A* PROGRAMMER - Steve Croy * A**************************************************************** A**************************************************************** A* FILE ATTRIBUTE SECTION * A* * A* KEY FIELDS: EXOBNM, EXOBTP * A* MAXMBRS : 1 * A* * A**************************************************************** A**************************************************************** A* MODIFICATION LOG * A* * A* DATE PROGRAMMER DESCRIPTION * A* * A**************************************************************** A UNIQUE A R RSCOBJS TEXT('OBJECT DATA') A EXCATS 3S 0 COLHDG('Cat' 'Cde') A TEXT('CATEGORY') A EXCSEQ 7S 0 COLHDG('Exec' 'Seq') A TEXT('Execution Sequence') A EXOBNM 10 COLHDG('Object' 'Name') A TEXT('OBJECT NAME') A EXOBTP 10 COLHDG('Object' 'Type') A TEXT('OBJECT TYPE') A EXDESC 50A COLHDG('Description') A TEXT('DESCRIPTION') A EXOBSR 10 COLHDG('Object' 'Source') A TEXT('OBJECT SOURCE') A EXOMBR 10 COLHDG('Source' 'Member') A TEXT('SOURCE MEMBER') A EXOBSL 10 COLHDG('Source' 'Library') A TEXT('SOURCE SOURCE') A EXCOMP 1 COLHDG('Cmp''Y/N') A TEXT('COMPILE Y/N') A EXMOVO 1 COLHDG('Mov''Y/N') A TEXT('MOVE OBJECT Y/N') A EXMOVS 1 COLHDG('MVS''Y/N') A TEXT('MOVE SOURCE Y/N') A EXACMD 1 COLHDG('Alt''Cmd') A TEXT('ALTERNATE COMMAND') A EXOBLB 10 COLHDG('Object' 'Library') A TEXT('OBJECT LIBRARY') *--- * AUDIT FIELDS *--- A EXADDT 8S 0 COLHDG('Added' 'Date') A TEXT('ADDED DATE') A EXADTM 6S 0 COLHDG('Added' 'Time') A TEXT('ADDED TIME') A EXADUS 10A COLHDG('Added' 'User') A TEXT('Added User') A EXCHDT 8S 0 COLHDG('Change' 'Date') A TEXT('Change Date') A EXCHTM 6S 0 COLHDG('Change' 'Time') A TEXT('Change Time') A EXCHUS 10A COLHDG('Change' 'User') A TEXT('Change User') *--- A EXPROC 1 COLHDG('Prc''Y/N') A TEXT('PROCESSED Y/N') A EXPRDT 8S 0 COLHDG('Processed' 'Date') A TEXT('Processed Date') A EXPRTM 6S 0 COLHDG('Processed' 'Time') A TEXT('Processed Time') A EXPRUS 10A COLHDG('Processed' 'by User') A TEXT('Processed by User') * A K EXOBNM A K EXOBTP
Table Note
The table includes a list of audit fields. These fields are not included in any SET procedure. That is deliberate; when the record is added, or changed, those fields will be handled interanlly by the service program. If the file is journalled, it should be easy to see the before and after image of the data. If the file is not journalled, it might be helpful to add output to a log file within the service program to provide an audit trail. This would ensure any change to the data would be recorded, independently from any other application.