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.