home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / db22fr.zip / FRDEMO.CMD next >
OS/2 REXX Batch file  |  1993-05-12  |  75KB  |  1,955 lines

  1. /*
  2.  ┌──────────────────────────────────────────────────────────────────┐
  3.  │  Name       : FRDEMO.cmd                                         │
  4.  │  Purpose    : Instigate various Forward Recovery scenarios       │
  5.  │  Platform   : IBM DB2/2, OS/2 2.1                                │
  6.  │  Author     : Jeff Fisher                                        │
  7.  │               Copyright IBM Corporation 1993                     │
  8.  │               IBM Toronto Development Lab                        │
  9.  │  Written    : 08/30/91 or thereabouts                            │
  10.  │                                                                  │
  11.  │  Notes      : You'll need to note the various drives and         │
  12.  │               directory names hard coded in this program.        │
  13.  │               Change them for your own system if needed.         │
  14.  │                                                                  │
  15.  │  Ideas      : - enter a timestamp                                │
  16.  │               - display options being used:                      │
  17.  │                 drive for database creation                      │
  18.  │                 database name user configurable                  │
  19.  │                 object qualifier user configurable               │
  20.  │               - log file values for circular logging??           │
  21.  │                 demonstrate primary and secondary by filling     │
  22.  │                 up all primary without committing                │
  23.  │                 and allow for alternate log file!                │
  24.  │               - help and about                                   │
  25.  │               - when inserting data, if the tables don't exist   │
  26.  │                 then exit the entire create path                 │
  27.  │               - option on menu to show the database flags:       │
  28.  │                 rollforward and backup pending.                  │
  29.  │               - RESUME and STOP should be allowed                │
  30.  │               - multiple recovery paths and DB backup versions   │
  31.  │                                                                  │
  32.  │                                                                  │
  33.  └──────────────────────────────────────────────────────────────────┘
  34. */
  35.  
  36. signal on syntax
  37. signal on error
  38.  
  39. call ProgramInitialize
  40. call MainMenu
  41. call EndProg
  42.  
  43.  
  44. MainMenu:
  45. /*
  46.  ┌──────────────────────────────────────────────────────────────────┐
  47.  │    MainMenu                                                      │
  48.  │                                                                  │
  49.  │    Main menu and control point for the entire program            │
  50.  │    Note use of REXXUTIL functions!                               │
  51.  │                                                                  │
  52.  └──────────────────────────────────────────────────────────────────┘
  53. */
  54.     call SysCls
  55.     say c.itcyan '******************************************'
  56.     say c.yellow ' FRDEMO Forward Recovery Instigator     '
  57.     say c.yellow '                                         '
  58.     say c.yellow ' _ 0   Menu: Program Options & Defaults   '
  59.     say c.yellow '                                         '
  60.     say c.yellow '   1   Menu: Database Objects             '
  61.     say c.yellow '   2   Menu: Adjust Tuning Parms          '
  62.     say c.yellow '   3   Menu: Do a Roll Forward sequence   '
  63.     say c.yellow '   4   Menu: Manipulate data in the DB    '
  64.     say c.yellow '   5   Menu: Utilities                    '
  65.     say c.yellow '   6   Menu: Tools                        '
  66.     say c.yellow '                                         '
  67.     say c.yellow '   x   Exit                               '
  68.     say c.yellow '                                         '
  69.     say c.itcyan '******************************************'
  70.     say c.itblue '     Copyright, IBM Corporation 1993      ' c.white
  71.  
  72.     row = 3
  73.     col = 2
  74.     pos = SysCurPos(row,col)
  75.     selection = SysGetKey('NOECHO')
  76.     call SysCls
  77.  
  78.     SELECT
  79.         WHEN selection = '0' then call ProgramOptions
  80.         WHEN selection = '1' then call ObjectMenu
  81.         WHEN selection = '2' then call ParmTuneMenu
  82.         WHEN selection = '3' then call RollForwardSequenceMenu
  83.         WHEN selection = '4' then call TableDataMenu
  84.         WHEN selection = '5' then call UtilityMenu
  85.         WHEN selection = '6' then call ToolsMenu
  86.         WHEN selection = 'x' then signal EndProg
  87.         OTHERWISE            NOP
  88.     END
  89.  
  90.     signal MainMenu
  91.  
  92.  
  93. ProgramOptions:
  94. /*
  95.  ┌──────────────────────────────────────────────────────────────────┐
  96.  │    ProgramOptions                                                │
  97.  │                                                                  │
  98.  │    Menu for selecting global program options & defaults          │
  99.  │                                                                  │
  100.  │                                                                  │
  101.  └──────────────────────────────────────────────────────────────────┘
  102. */
  103.     call SysCls
  104.     say c.itcyan '******************************************'
  105.     say c.yellow ' Program Options & Defaults              '
  106.     say c.yellow '                                          '
  107.     say c.yellow ' _ 1   Show   Timings                      '
  108.     say c.yellow '   2   Change DBdrive                      '
  109.     say c.yellow '   3   Change DBname                       '
  110.     say c.yellow '   4   Change DBprefix                     '
  111.     say c.yellow '                                          '
  112.     say c.yellow '   x   Exit                               '
  113.     say c.itcyan '******************************************' c.white
  114.  
  115.     row = 3
  116.     col = 2
  117.     pos = SysCurPos(row,col)
  118.     selection = SysGetKey('NOECHO')
  119.     call SysCls
  120.  
  121.     SELECT
  122.         WHEN selection = '1' then     OptionTiming = 'Y'
  123.         WHEN selection = '2' then     say 'not implemented yet'
  124.         WHEN selection = '3' then     say 'not implemented yet'
  125.         WHEN selection = '4' then     say 'not implemented yet'
  126.         OTHERWISE            NOP
  127.     END
  128.  
  129.     return
  130.  
  131.  
  132. ObjectMenu:
  133. /*
  134.  ┌──────────────────────────────────────────────────────────────────┐
  135.  │    ObjectMenu                                                    │
  136.  │                                                                  │
  137.  │    Menu for setting up all relational objects used:              │
  138.  │                                                                  │
  139.  │            Database                                              │
  140.  │            Tables                                                │
  141.  │            Indexes                                               │
  142.  │                                                                  │
  143.  └──────────────────────────────────────────────────────────────────┘
  144. */
  145.     call SysCls
  146.     say c.itcyan '******************************************'
  147.     say c.yellow ' Object Menu                             '
  148.     say c.yellow '                                          '
  149.     say c.yellow ' _ 1   Create database FRDEMO              '
  150.     say c.yellow '   2   Create application tables           '
  151.     say c.yellow '   3   Create application indexes          '
  152.     say c.yellow '                                          '
  153.     say c.yellow '   4   Drop database FRDEMO                '
  154.     say c.yellow '   5   Drop application tables             '
  155.     say c.yellow '   6   Drop application indexes            '
  156.     say c.yellow '                                          '
  157.     say c.yellow '   x   Exit                               '
  158.     say c.itcyan '******************************************' c.white
  159.  
  160.     row = 3
  161.     col = 2
  162.     pos = SysCurPos(row,col)
  163.     selection = SysGetKey('NOECHO')
  164.     call SysCls
  165.  
  166.     SELECT
  167.         WHEN selection = '1' then call CreateFRDEMO
  168.         WHEN selection = '2' then call CreateTables
  169.         WHEN selection = '3' then call CreateIndexes
  170.         WHEN selection = '4' then call DropFRDEMO
  171.         WHEN selection = '5' then call DropTables
  172.         WHEN selection = '6' then call DropIndexes
  173.         WHEN selection = 'x' then return
  174.         OTHERWISE            NOP
  175.     END
  176.  
  177.     return
  178.  
  179.  
  180. ParmTuneMenu:
  181. /*
  182.  ┌──────────────────────────────────────────────────────────────────┐
  183.  │    ParmTuneMenu                                                  │
  184.  │                                                                  │
  185.  │    Menu for tuning the DBM and the test database:                │
  186.  │                                                                  │
  187.  │            Tune for Forward Recovery      + high-perf parms      │
  188.  │            Tune for no Forward Recovery   + high-perf-parms      │
  189.  │            Tune for no Forward Recovery   + low-perf parms       │
  190.  │                                                                  │
  191.  └──────────────────────────────────────────────────────────────────┘
  192. */
  193.     call SysCls
  194.     say c.itcyan '******************************************'
  195.     say c.yellow ' DB and DBM Parameter Tuning Menu        '
  196.     say c.yellow '                                          '
  197.     say c.yellow ' _ 1   Performance, FR & SQLUEXIT/yes      '
  198.     say c.yellow '   2   Performance, FR & SQLUEXIT/no       '
  199.     say c.yellow '   3   Base default lo-po parms            '
  200.     say c.yellow '                                          '
  201.     say c.yellow '   x   Exit                               '
  202.     say c.itcyan '******************************************' c.white
  203.  
  204.     row = 3
  205.     col = 2
  206.     pos = SysCurPos(row,col)
  207.     selection = SysGetKey('NOECHO')
  208.     call SysCls
  209.  
  210.     SELECT
  211.         WHEN selection = '1' then call MegaTuningParms
  212.         WHEN selection = '2' then call PerfTuningParms
  213.         WHEN selection = '3' then call BaseTuningParms
  214.         WHEN selection = 'x' then return
  215.         OTHERWISE            NOP
  216.     END
  217.  
  218.     return
  219.  
  220.  
  221. TableDataMenu:
  222. /*
  223.  ┌──────────────────────────────────────────────────────────────────┐
  224.  │    TableDataMenu                                                 │
  225.  │                                                                  │
  226.  │    Menu for putting data in the tables:                          │
  227.  │                                                                  │
  228.  │            From IMPORT (or EXPORT data out)                      │
  229.  │             - helps you save your "favorite" data                │
  230.  │            From INSERTs                                          │
  231.  │             - builds data and commits at intervals               │
  232.  │                                                                  │
  233.  └──────────────────────────────────────────────────────────────────┘
  234. */
  235.     call SysCls
  236.     say c.itcyan '******************************************'
  237.     say c.yellow ' Table Data Menu                         '
  238.     say c.yellow '                                          '
  239.     say c.yellow ' _ 1   EXPORT data from employee           '
  240.     say c.yellow '   2   IMPORT data to   employee           '
  241.     say c.yellow '   3   Create data for all tables          '
  242.     say c.yellow '                                           '
  243.     say c.yellow '   x   Exit                               '
  244.     say c.itcyan '******************************************' c.white
  245.  
  246.     row = 3
  247.     col = 2
  248.     pos = SysCurPos(row,col)
  249.     selection = SysGetKey('NOECHO')
  250.     call SysCls
  251.  
  252.     SELECT
  253.         WHEN selection = '1' then call EXPORTemployee
  254.         WHEN selection = '2' then call IMPORTemployee
  255.         WHEN selection = '3' then call PopulateMenu
  256.         WHEN selection = 'x' then return
  257.         OTHERWISE            NOP
  258.     END
  259.  
  260.     return
  261.  
  262.  
  263. PopulateMenu:
  264. /*
  265.  ┌──────────────────────────────────────────────────────────────────┐
  266.  │    PopulateMenu                                                  │
  267.  │                                                                  │
  268.  │    Each table can be done in turn, or all can be done            │
  269.  │  together in the intended sequence. Each gets it's own CONNECT   │
  270.  │  and CONNECT RESET, thus creating separate logs for each table.  │
  271.  │    COMMIT or ROLLBACK is an option, allowing you to see that     │
  272.  │  either option does in fact end up in the logs.                  │
  273.  │    The tables are populated via a lot of comcatenated strings.   │
  274.  │  This is not a very good method, as concatenation of these       │
  275.  │  strings in rexx seems to take a lot of CPU time. Therefore, the │
  276.  │  insert rate is limited ot about 12 per second. It could         │
  277.  │  probably be much faster with a better method.                   │
  278.  │                                                                  │
  279.  └──────────────────────────────────────────────────────────────────┘
  280. */
  281.     if EmployeeRowCount > 99999 then EmployeeRandomCount = 99999
  282.     else EmployeeRandomCount = EmployeeRowCount
  283.  
  284.     call SysCls
  285.     say c.itcyan '******************************************'
  286.     say c.yellow ' Populate Tables menu                    '
  287.     say c.yellow '                                         '
  288.     say c.yellow ' _ 0   Populate all tables in sequence     '
  289.     say c.yellow '                                          '
  290.     say c.yellow '   1   Table: DIRECTORATE                  '
  291.     say c.yellow '   2   Table: DIVISION                     '
  292.     say c.yellow '   3   Table: DEPARTMENT                   '
  293.     say c.yellow '   4   Table: EMPLOYEE                     '
  294.     say c.yellow '                                         '
  295.     say c.yellow '   x   Exit                               '
  296.     say c.yellow '                                         '
  297.     say c.itcyan '******************************************' c.white
  298.  
  299.     row = 3
  300.     col = 2
  301.     pos = SysCurPos(row,col)
  302.     selection = SysGetKey('NOECHO')
  303.     call SysCls
  304.  
  305.     SELECT
  306.         WHEN selection = '0' then
  307.                                  do
  308.                                      call PopulateDirectorate
  309.                                      call PopulateDivision
  310.                                      call PopulateDepartment
  311.                                      call PopulateEmployee
  312.                                  end
  313.         WHEN selection = '1' then call PopulateDirectorate
  314.         WHEN selection = '2' then call PopulateDivision
  315.         WHEN selection = '3' then call PopulateDepartment
  316.         WHEN selection = '4' then call PopulateEmployee
  317.         WHEN selection = 'x' then return
  318.         OTHERWISE            NOP
  319.     END
  320.  
  321.     return
  322.  
  323.  
  324. RollForwardSequenceMenu:
  325. /*
  326.  ┌──────────────────────────────────────────────────────────────────┐
  327.  │    RollForwardSequenceMenu                                       │
  328.  │                                                                  │
  329.  │    Running utilities against the database:                       │
  330.  │                                                                  │
  331.  │            Restore            before Forward Recovery            │
  332.  │            Roll Forward       during Forward Recovery            │
  333.  │                                                                  │
  334.  │                               what happens after?                │
  335.  │                                                                  │
  336.  └──────────────────────────────────────────────────────────────────┘
  337. */
  338.     call SysCls
  339.     say c.itcyan '******************************************'
  340.     say c.yellow ' Roll Forward Sequence Menu              '
  341.     say c.yellow '                                          '
  342.     say c.yellow ' _ 1   Restore before Forward Recovery      '
  343.     say c.yellow '   2   Roll Forward the database            '
  344.     say c.yellow '   3   both steps 1 and 2                   '
  345.     say c.yellow '                                          '
  346.     say c.yellow '   x   Exit                               '
  347.     say c.yellow '                                          '
  348.     say c.itcyan '******************************************' c.white
  349.  
  350.     row = 3
  351.     col = 2
  352.     pos = SysCurPos(row,col)
  353.     selection = SysGetKey('NOECHO')
  354.     call SysCls
  355.  
  356.     SELECT
  357.         WHEN selection = '1' then call Roll1
  358.         WHEN selection = '2' then call Roll2
  359.         WHEN selection = '3' then
  360.             do
  361.                 call Roll1
  362.                 call Roll2
  363.             end
  364.         WHEN selection = 'x' then return
  365.         OTHERWISE            NOP
  366.     END
  367.  
  368.     return
  369.  
  370.  
  371. ToolsMenu:
  372. /*
  373.  ┌──────────────────────────────────────────────────────────────────┐
  374.  │    ToolsMenu                                                     │
  375.  │                                                                  │
  376.  │    LOG              - starts Monitor of LOGS                     │
  377.  │    DB               - starts Monitor of Database                 │
  378.  │                                                                  │
  379.  └──────────────────────────────────────────────────────────────────┘
  380. */
  381.     call SysCls
  382.     say c.itcyan '******************************************'
  383.     say c.yellow ' Tools Menu                              '
  384.     say c.yellow '                                          '
  385.     say c.yellow ' _ 1   Start LOG Monitor                    '
  386.     say c.yellow '   2   Start DB  Monitor                    '
  387.     say c.yellow '                                          '
  388.     say c.yellow '   x   Exit                               '
  389.     say c.yellow '                                          '
  390.     say c.itcyan '******************************************' c.white
  391.  
  392.     row = 3
  393.     col = 2
  394.     pos = SysCurPos(row,col)
  395.     selection = SysGetKey('NOECHO')
  396.     call SysCls
  397.  
  398.     SELECT
  399.         WHEN selection = '1' then call StartMonLOG
  400.         WHEN selection = '2' then call StartMonDB
  401.         WHEN selection = 'x' then return
  402.         OTHERWISE            NOP
  403.     END
  404.  
  405.     return
  406.  
  407.  
  408. UtilityMenu:
  409. /*
  410.  ┌──────────────────────────────────────────────────────────────────┐
  411.  │    UtilityMenu                                                   │
  412.  │                                                                  │
  413.  │    Runstats & Reorg - demonstrate the effect on the logs         │
  414.  │                       from these utilities                       │
  415.  │                                                                  │
  416.  │    Backup           - does the necessary backup after turning    │
  417.  │                       on Forward Recovery                        │
  418.  │                                                                  │
  419.  │    Notes: Explicit qualifiers are used on all object names       │
  420.  │           so that these utilities don't have to find out         │
  421.  │           what (implicit) qualifier is being used.               │
  422.  │                                                                  │
  423.  └──────────────────────────────────────────────────────────────────┘
  424. */
  425.     call SysCls
  426.     say c.itcyan '******************************************'
  427.     say c.yellow ' Utility Menu                            '
  428.     say c.yellow '                                          '
  429.     say c.yellow ' _ 1   Reorg all tables                     '
  430.     say c.yellow '   2   Runstats the tables                  '
  431.     say c.yellow '   3   Backup the entire database           '
  432.     say c.yellow '                                          '
  433.     say c.yellow '   x   Exit                               '
  434.     say c.yellow '                                          '
  435.     say c.itcyan '******************************************' c.white
  436.  
  437.     row = 3
  438.     col = 2
  439.     pos = SysCurPos(row,col)
  440.     selection = SysGetKey('NOECHO')
  441.     call SysCls
  442.  
  443.     SELECT
  444.         WHEN selection = '1' then call ReorgTables
  445.         WHEN selection = '2' then call RunstatTables
  446.         WHEN selection = '3' then call BackupDB
  447.         WHEN selection = 'x' then return
  448.         OTHERWISE            NOP
  449.     END
  450.  
  451.     return
  452.  
  453.  
  454. ReorgTables:
  455. /*
  456.  ┌──────────────────────────────────────────────────────────────────┐
  457.  │    ReorgTables                                                   │
  458.  │                                                                  │
  459.  │    Does reorgs on all tables with appropriate qualifiers         │
  460.  │                                                                  │
  461.  └──────────────────────────────────────────────────────────────────┘
  462. */
  463.     say c.itgreen '---> REORG all tables'
  464.  
  465.     call ReorgUtility 'FRDEMO.EMPLOYEE' 'FRDEMO.EMPLOYEE_ID_I'
  466.     call ReorgUtility 'FRDEMO.DIVISION' 'FRDEMO.DIVISION_I'
  467.     call ReorgUtility 'FRDEMO.DIRECTORATE' 'FRDEMO.DIRECTORATE_I'
  468.     call ReorgUtility 'FRDEMO.DEPARTMENT' 'FRDEMO.DEPARTMENT_DEPT_I'
  469.  
  470.     return
  471.  
  472.  
  473. RunstatTables:
  474. /*
  475.  ┌──────────────────────────────────────────────────────────────────┐
  476.  │    RunstatTables                                                 │
  477.  │                                                                  │
  478.  │    Does runstats on all tables                                   │
  479.  │                                                                  │
  480.  └──────────────────────────────────────────────────────────────────┘
  481. */
  482.     say c.itgreen '---> RUNSTATS all tables'
  483.  
  484.     call RunstatUtility 'FRDEMO.EMPLOYEE' 'FRDEMO.EMPLOYEE_ID_I'
  485.     call RunstatUtility 'FRDEMO.DIVISION' 'FRDEMO.DIVISION_I'
  486.     call RunstatUtility 'FRDEMO.DIRECTORATE' 'FRDEMO.DIRECTORATE_I'
  487.     call RunstatUtility 'FRDEMO.DEPARTMENT' 'FRDEMO.DEPARTMENT_DEPT_I'
  488.  
  489.     return
  490.  
  491.  
  492. BackupDB:
  493. /*
  494.  ┌──────────────────────────────────────────────────────────────────┐
  495.  │    BackupDB                                                      │
  496.  │                                                                  │
  497.  │    Backs up the database (using the user exit). The user exit    │
  498.  │  must be found in a PATH.                                        │
  499.  │                                                                  │
  500.  └──────────────────────────────────────────────────────────────────┘
  501. */
  502.     say c.itgreen '---> Backup to drive 0'
  503.     step = 'Backup DB to drive 0 (user exit invokation)'
  504.     CALL SQLDBS 'BACKUP DATABASE' DBname 'ALL TO 0'
  505.     if SQLCA.SQLCODE = -2029 then
  506.         do
  507.             say
  508.             say c.itred '          **** USER EXIT FATAL ERROR ****'
  509.             say   c.red '               Program will continue     '
  510.             say   c.red '               after display of SQLCA    '
  511.             call SoftErrorSQL
  512.             return
  513.         end
  514.     else
  515.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  516.  
  517.     return
  518.  
  519.  
  520. StartMonDB:
  521. /*
  522.  ┌──────────────────────────────────────────────────────────────────┐
  523.  │    StartMonDB                                                    │
  524.  │                                                                  │
  525.  │    Start Monitor for Database                                    │
  526.  │                                                                  │
  527.  └──────────────────────────────────────────────────────────────────┘
  528. */
  529.     say c.itgreen '     ---> Start DB Monitor'
  530.     step = 'start monitor'
  531.     address cmd 'start mon_db.cmd'
  532.     if RC \= 0 then signal ErrorRC
  533.  
  534.     return
  535.  
  536. StartMonLOG:
  537. /*
  538.  ┌──────────────────────────────────────────────────────────────────┐
  539.  │    StartMonLOG                                                   │
  540.  │                                                                  │
  541.  │    Start Monitor for LOGS                                        │
  542.  │                                                                  │
  543.  └──────────────────────────────────────────────────────────────────┘
  544. */
  545.     say c.itgreen '     ---> Start LOG Monitor'
  546.     step = 'start monitor'
  547.     address cmd 'start mon_logs.cmd'
  548.     if RC \= 0 then signal ErrorRC
  549.  
  550.     return
  551.  
  552.  
  553. ReorgUtility:
  554. /*
  555.  ┌──────────────────────────────────────────────────────────────────┐
  556.  │    ReorgUtility                                                  │
  557.  │                                                                  │
  558.  │    Performs a REORG                                              │
  559.  │                                                                  │
  560.  │    Individual Connect/ConnectResets are done for each so that    │
  561.  │    the user can see when the log file is done with during the    │
  562.  │    utility process                                               │
  563.  │                                                                  │
  564.  └──────────────────────────────────────────────────────────────────┘
  565. */
  566.     arg ReorgTable ReorgIndex
  567.  
  568.     step = 'REORG'
  569.  
  570.     call Connect
  571.  
  572.     say c.itblue '     REORG' ReorgTable
  573.     say c.itblue '      in' DBname
  574.     say c.itblue '      w/ index' ReorgIndex
  575.  
  576.     call TimingsBegin
  577.  
  578.     call SQLDBS 'REORG TABLE' ReorgTable,
  579.                 ' IN' DBname,
  580.                 ' INDEX' ReorgIndex
  581.     if SQLCA.SQLCODE = -2205 then
  582.         do
  583.             say
  584.             say c.itred 'Specified Index does not exist yet'
  585.             say c.itred 'press <enter> to continue'
  586.             nimnull = SysGetKey('NOECHO')
  587.             return
  588.         end
  589.     else
  590.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  591.  
  592.     call TimingsEnd
  593.  
  594.     call ConnectReset
  595.  
  596.     return
  597.  
  598.  
  599. RunstatUtility:
  600. /*
  601.  ┌──────────────────────────────────────────────────────────────────┐
  602.  │    RunstatUtility                                                │
  603.  │                                                                  │
  604.  │    Performs a RUNSTAT                                            │
  605.  │                                                                  │
  606.  │    Individual Connect/ConnectResets are done for each so that    │
  607.  │    the user can see when the log file is done with during the    │
  608.  │    utility process                                               │
  609.  │                                                                  │
  610.  └──────────────────────────────────────────────────────────────────┘
  611. */
  612.     arg RunstatTable RunstatIndex
  613.  
  614.     step = 'RUNSTATS'
  615.  
  616.     RunIndex.0 = 1
  617.     RunIndex.1 = RunstatIndex
  618.  
  619.     call Connect
  620.  
  621.     say c.itblue '     RUNSTAT' RunstatTable
  622.     say c.itblue '      for index' RunstatIndex
  623.  
  624.     call TimingsBegin
  625.  
  626.     call SQLDBS 'RUNSTATS ON TABLE' RunstatTable,
  627.                 ' AND INDEXES USING :RunIndex'
  628.  
  629.     if SQLCA.SQLCODE = -2306 then
  630.         do
  631.             say
  632.             say c.itred 'Specified Index does not exist yet'
  633.             say c.itred 'press <enter> to continue'
  634.             nimnull = SysGetKey('NOECHO')
  635.             return
  636.         end
  637.     else
  638.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  639.  
  640.     call ConnectReset
  641.     call TimingsEnd
  642.  
  643.     return
  644.  
  645.  
  646. Roll1:
  647. /*
  648.  ┌──────────────────────────────────────────────────────────────────┐
  649.  │    Roll1                                                         │
  650.  │                                                                  │
  651.  │    Restore the database, calling the USER EXIT.                  │
  652.  │    Check to see if the database exists, if it does, the DBM      │
  653.  │    sends back an SQLCODE "for your protection".                  │
  654.  │                                                                  │
  655.  └──────────────────────────────────────────────────────────────────┘
  656. */
  657.     say c.itgreen '---> Restore from drive 0'
  658.     step = 'restore database'
  659.  
  660.     call TimingsBegin
  661.  
  662.     CALL SQLDBS 'RESTORE DATABASE' DBname,
  663.                 'from 0 to' DBdrive
  664.  
  665. /*   'without rolling forward' <- makes it impossible to
  666.       do forward recovery - you get an sqlcode back that says
  667.       the database doesn't need rolling forward (sqlcode -1261) */
  668.  
  669.  
  670.     if SQLCA.SQLCODE = -2029 then
  671.         do
  672.             say
  673.             say c.itred '          **** USER EXIT FATAL ERROR ****'
  674.             say   c.red '               Program will continue     '
  675.             say   c.red '               after display of SQLCA    '
  676.             call SoftErrorSQL
  677.         return
  678.         end
  679.     else
  680.         if SQLCA.SQLCODE = +2505 then
  681.             do
  682.                 call beep 100,50
  683.                 say c.itred   'SQLCODE +2505'
  684.                 say c.itred   'Warning: You about to write over '
  685.                 say c.itred   '  the existing database:  '
  686.                 say c.itred   '  press <y> to continue   '
  687.                 say c.itred   '        <n> to terminate  '
  688.                 ContRF = SysGetKey('NOECHO')
  689.                 if ContRF = 'Y' | ContRF = 'y' then
  690.                     do
  691.                         call TimingsEnd
  692.                         signal Roll1a
  693.                     end
  694.                 else
  695.                     ContRF = 'N'
  696.                     return
  697.             end
  698.         else
  699.             if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  700.  
  701.     call TimingsEnd
  702.  
  703.     return
  704.  
  705.  
  706. Roll1a:
  707. /*
  708.  ┌──────────────────────────────────────────────────────────────────┐
  709.  │    Roll1a                                                        │
  710.  │                                                                  │
  711.  │    Ok, continue the restore. Make sure nobody is connected.      │
  712.  │                                                                  │
  713.  └──────────────────────────────────────────────────────────────────┘
  714. */
  715.     say c.itgreen '---> Continue restore'
  716.     step = 'continue restore'
  717.  
  718.     call TimingsBegin
  719.  
  720.     call sqldbs 'CONTINUE RESTORE'
  721.     if SQLCA.SQLCODE = +2520 then
  722.         do
  723.             call beep 100,50
  724.             say c.itred 'SQLCODE +2520'
  725.             say c.itred 'Info: the database has been restored: '
  726.             say c.itred '  the backup version of the config    '
  727.             say c.itred '  file was used                       '
  728.             say c.itred '    press <enter> to continue   '
  729.             nimnull = SysGetKey('NOECHO')
  730.         end
  731.     else
  732.         if SQLCA.SQLCODE = -2010 then
  733.             do
  734.                 call beep 100,50
  735.                 say c.itred 'SQLCODE -2010'
  736.                 say c.itred 'Another application is connected to   '
  737.                 say c.itred '  the DB - please disconnect them     '
  738.                 say c.itred '  so that this can continue           '
  739.                 say c.itred '    press <enter> to continue   '
  740.                 nimnull = SysGetKey('NOECHO')
  741.                 signal Roll1
  742. /* -2010 is fatal - start all over again   */
  743.             end
  744.     else
  745.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  746.  
  747.     call TimingsEnd
  748.  
  749.     return
  750.  
  751.  
  752. Roll2:
  753. /*
  754.  ┌──────────────────────────────────────────────────────────────────┐
  755.  │    Roll2                                                         │
  756.  │                                                                  │
  757.  │    Roll forward to the end of the logs.                          │
  758.  │                                                                  │
  759.  └──────────────────────────────────────────────────────────────────┘
  760. */
  761.     if ContRF = 'N' then return
  762.     say c.itgreen '---> Roll Forward'
  763.     step = 'roll forward database'
  764.  
  765.     call TimingsBegin
  766.  
  767.     CALL SQLDBS 'rollforward database' DBname,
  768.                 'to end of logs ',
  769.                 'and stop'
  770.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  771.  
  772.     call TimingsEnd
  773.  
  774.     return
  775.  
  776.  
  777. EXPORTemployee:
  778. /*
  779.  ┌──────────────────────────────────────────────────────────────────┐
  780.  │    EXPORTemployee                                                │
  781.  │                                                                  │
  782.  │    Export the entire EMPLOYEE table. This is here because this   │
  783.  │    is the largest table. You can edit the EXPORTed table to      │
  784.  │    add more employees or special case rows.                      │
  785.  │                                                                  │
  786.  └──────────────────────────────────────────────────────────────────┘
  787. */
  788.     say c.itgreen '---> Export Employee'
  789.     step = 'Export employee'
  790.     exp = 'select * from employee order by id'
  791.  
  792.     call Connect
  793.     CALL SQLDBS 'EXPORT :exp FROM' DBname,
  794.                 'TO f:\FRDEMO\emp OF del ',
  795.                 'MESSAGES msgexp.txt'
  796.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  797.     call ConnectReset
  798.  
  799.     return
  800.  
  801.  
  802. IMPORTemployee:
  803. /*
  804.  ┌──────────────────────────────────────────────────────────────────┐
  805.  │    IMPORTemployee                                                │
  806.  │                                                                  │
  807.  │    Import the employee table. Table must be named                │
  808.  │    "employee.del" and exist in the same directory as this.       │
  809.  │                                                                  │
  810.  └──────────────────────────────────────────────────────────────────┘
  811. */
  812.     say c.itgreen '---> Import Employee'
  813.     step = 'Import employee'
  814.  
  815.     call Connect
  816.     call TimingsBegin
  817.     CALL SQLDBS 'IMPORT to FRDEMO from       ',
  818.                 'employee.del of del         ',
  819.                 'insert into userid.employee ',
  820.                 'MESSAGES msginp.txt         '
  821.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  822.  
  823.     call ConnectReset
  824.     call TimingsEnd
  825.  
  826.     return
  827.  
  828.  
  829. MegaTuningParms:
  830. /*
  831.  ┌──────────────────────────────────────────────────────────────────┐
  832.  │    MegaTuningParms                                               │
  833.  │                                                                  │
  834.  │    Set all values high:                                          │
  835.  │      DBM sqlenseg to the max                                     │
  836.  │      DB  buffpool and related parms very high                    │
  837.  │      DB  log retain and user exit ON                             │
  838.  │                                                                  │
  839.  └──────────────────────────────────────────────────────────────────┘
  840. */
  841.     say c.itgreen '---> Set the DBM parms to MEGA values'
  842.     step = 'default DBM parms'
  843.     dbmval.0 = 2
  844.     dbmval.1 = 5                   /* sqlenseg             */
  845.     dbmval.2 = 1200
  846.     CALL SQLDBS 'UPDATE DATABASE MANAGER CONFIGURATION',
  847.                 'USING :dbmval'
  848.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  849.     call StopDBM
  850.     call StartDBM
  851.  
  852.     say c.itgreen '---> Set the DB parms to MEGA values'
  853.     step = 'Mega DB parms'
  854.     call Connect
  855. /*  ARRAY          PARM     VALUE            DESCRIPTION        */
  856.     dbval.0 = 16
  857.     dbval.1   =     16
  858.     dbval.2   =                3        /*   log primary        */
  859.     dbval.3   =     17
  860.     dbval.4   =                5        /*   log secondary      */
  861.     dbval.5   =     18
  862.     dbval.6   =              500        /*   log file size      */
  863.     dbval.7   =      2
  864.     dbval.8   =              800        /*   buffpage           */
  865.     dbval.9   =      8
  866.     dbval.10  =                4        /*   db heap            */
  867.     dbval.11  =     11
  868.     dbval.12  =               10        /*   sort heap          */
  869.     dbval.13  =     19
  870.     dbval.14  =              128        /*   stmt heap          */
  871.     dbval.15  =     21
  872.     dbval.16  =               15        /*   attributes         */
  873.  
  874.     CALL SQLDBS 'UPDATE DATABASE CONFIGURATION',
  875.                 'FOR' DBname,
  876.                 'USING :dbval'
  877.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  878.     call ConnectReset
  879.  
  880.     say
  881.     say c.yellow  '       -> Tuning is at MEGA values'
  882.     say c.yellow  '       -> Database Manager:'
  883.     say c.itgreen '            sqlenseg     ='  dbmval.2
  884.     say c.yellow  '       -> Database:'
  885.     say c.itgreen '            logprimary   ='  dbval.2
  886.     say c.itgreen '            logsecondary ='  dbval.4
  887.     say c.itgreen '            logfilsiz    ='  dbval.6
  888.     say c.itgreen '            buffpage     ='  dbval.8
  889.     say c.itgreen '            dbheap       ='  dbval.10
  890.     say c.itgreen '            sortheap     ='  dbval.12
  891.     say c.itgreen '            stmtheap     ='  dbval.14
  892.     say c.itgreen '            attribute    ='  dbval.16
  893.     pause
  894.  
  895.     return
  896.  
  897.  
  898. PerfTuningParms:
  899. /*
  900.  ┌──────────────────────────────────────────────────────────────────┐
  901.  │    PerfTuningParms                                               │
  902.  │                                                                  │
  903.  │    Set all values high:                                          │
  904.  │      DBM sqlenseg to the max                                     │
  905.  │      DB  buffpool and related parms very high                    │
  906.  │      DB  log retain and user exit OFF                            │
  907.  │                                                                  │
  908.  └──────────────────────────────────────────────────────────────────┘
  909. */
  910.     say c.itgreen '---> Set the DBM parms to perf values'
  911.     step = 'Perf DBM parms'
  912.     dbmval.0 = 2
  913.     dbmval.1 = 5                   /* sqlenseg             */
  914.     dbmval.2 = 802
  915.     CALL SQLDBS 'UPDATE DATABASE MANAGER CONFIGURATION',
  916.                 'USING :dbmval'
  917.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  918.     call StopDBM
  919.     call StartDBM
  920.  
  921.     say c.itgreen '---> Set the DB parms to perf values'
  922.     step = 'default DB parms'
  923.     call Connect
  924.                                    /* parm array           */
  925.     dbval.0  = 14
  926.     dbval.1  = 16                  /* log primary          */
  927.     dbval.2  = 3
  928.     dbval.3  = 17                  /* log secondary        */
  929.     dbval.4  = 4
  930.     dbval.5  = 18                  /* log file size        */
  931.     dbval.6  = 500
  932.     dbval.7  = 2                   /* buffpage             */
  933.     dbval.8  = 800
  934.     dbval.9  = 8                   /* db heap              */
  935.     dbval.10 = 4
  936.     dbval.11 = 11                  /* sort heap            */
  937.     dbval.12 = 10
  938.     dbval.13 = 19                  /* stmt heap            */
  939.     dbval.14 = 128
  940.  
  941.     CALL SQLDBS 'UPDATE DATABASE CONFIGURATION',
  942.                 'FOR' DBname,
  943.                 'USING :dbval'
  944.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  945.     call ConnectReset
  946.  
  947.     say
  948.     say c.yellow  '       -> Tuning is at PERF values'
  949.     say c.yellow  '       -> Database Manager:'
  950.     say c.itgreen '            sqlenseg     ='  dbmval.2
  951.     say c.yellow  '       -> Database:'
  952.     say c.itgreen '            logprimary   ='  dbval.2
  953.     say c.itgreen '            logsecondary ='  dbval.4
  954.     say c.itgreen '            logfilsiz    ='  dbval.6
  955.     say c.itgreen '            buffpage     ='  dbval.8
  956.     say c.itgreen '            dbheap       ='  dbval.10
  957.     say c.itgreen '            sortheap     ='  dbval.12
  958.     say c.itgreen '            stmtheap     ='  dbval.14
  959.     pause
  960.  
  961.     return
  962.  
  963.  
  964. BaseTuningParms:
  965. /*
  966.  ┌──────────────────────────────────────────────────────────────────┐
  967.  │    BaseTuningParms                                               │
  968.  │                                                                  │
  969.  │    Set all values high:                                          │
  970.  │      DBM sqlenseg to the max                                     │
  971.  │      DB  buffpool and related parms low                          │
  972.  │      DB  log retain and user exit OFF                            │
  973.  │                                                                  │
  974.  └──────────────────────────────────────────────────────────────────┘
  975. */
  976.     say c.itgreen '---> Set the DBM parms to base values'
  977.     step = 'base DBM parms'
  978.     dbmval.0 = 2
  979.     dbmval.1 = 5                   /* sqlenseg             */
  980.     dbmval.2 = 802
  981.     CALL SQLDBS 'UPDATE DATABASE MANAGER CONFIGURATION',
  982.                 'USING :dbmval'
  983.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  984.     call StopDBM
  985.     call StartDBM
  986.  
  987.     say c.itgreen '---> Set the DB parms to base values'
  988.     step = 'default DB parms'
  989.     call Connect
  990.                                    /* parm array           */
  991.     dbval.0  = 14
  992.     dbval.1  = 16                  /* log primary          */
  993.     dbval.2  = 2
  994.     dbval.3  = 17                  /* log secondary        */
  995.     dbval.4  = 2
  996.     dbval.5  = 18                  /* log file size        */
  997.     dbval.6  = 500
  998.     dbval.7  = 2                   /* buffpage             */
  999.     dbval.8  = 500
  1000.     dbval.9  = 8                   /* db heap              */
  1001.     dbval.10 = 4
  1002.     dbval.11 = 11                  /* sort heap            */
  1003.     dbval.12 = 10
  1004.     dbval.13 = 19                  /* stmt heap            */
  1005.     dbval.14 = 128
  1006.  
  1007.     CALL SQLDBS 'UPDATE DATABASE CONFIGURATION',
  1008.                 'FOR' DBname,
  1009.                 'USING :dbval'
  1010.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1011.     call ConnectReset
  1012.  
  1013.     say
  1014.     say c.yellow  '       -> Tuning is at BASE'
  1015.     say c.yellow  '       -> Database Manager:'
  1016.     say c.itgreen '            sqlenseg     ='  dbmval.2
  1017.     say c.yellow  '       -> Database:'
  1018.     say c.itgreen '            logprimary   ='  dbval.2
  1019.     say c.itgreen '            logsecondary ='  dbval.4
  1020.     say c.itgreen '            logfilsiz    ='  dbval.6
  1021.     say c.itgreen '            buffpage     ='  dbval.8
  1022.     say c.itgreen '            dbheap       ='  dbval.10
  1023.     say c.itgreen '            sortheap     ='  dbval.12
  1024.     say c.itgreen '            stmtheap     ='  dbval.14
  1025.     pause
  1026.  
  1027.     return
  1028.  
  1029.  
  1030. CreateFRDEMO:
  1031. /*
  1032.  ┌──────────────────────────────────────────────────────────────────┐
  1033.  │    CreateFRDEMO                                                  │
  1034.  │                                                                  │
  1035.  │    Create the database. Currently doesn't allow the user         │
  1036.  │    to specify which drive to use. This would be a problem        │
  1037.  │    when this code is released.                                   │
  1038.  │                                                                  │
  1039.  └──────────────────────────────────────────────────────────────────┘
  1040. */
  1041.     say c.itgreen '---> CREATE database' DBname 'on drive' DBdrive
  1042.     step = 'Create database' DBname
  1043.     call TimingsBegin
  1044.  
  1045.     call SQLDBS 'CREATE DATABASE' DBname 'ON' DBdrive
  1046.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1047.  
  1048.     Call TimingsEnd
  1049.  
  1050.     return
  1051.  
  1052.  
  1053. CreateTables:
  1054. /*
  1055.  ┌──────────────────────────────────────────────────────────────────┐
  1056.  │    CreateTables                                                  │
  1057.  │                                                                  │
  1058.  │    Create all tables used int he test. These tables are          │
  1059.  │    roughly "referentially" related to one another. That isn't    │
  1060.  │    the point of this test, so RI is not actually used.           │
  1061.  │                                                                  │
  1062.  └──────────────────────────────────────────────────────────────────┘
  1063. */
  1064.     say c.itgreen '---> CREATE application TABLEs'
  1065.  
  1066.     table1 = 'CREATE TABLE FRDEMO.EMPLOYEE',
  1067.               '(ID          integer       NOT NULL,',
  1068.               ' NAME        CHAR(75)      NOT NULL,',
  1069.               ' address1    CHAR(75)      NOT NULL,',
  1070.               ' address2    CHAR(75)      NOT NULL,',
  1071.               ' address3    CHAR(75)      NOT NULL,',
  1072.               ' address4    CHAR(75)      NOT NULL,',
  1073.               ' state       CHAR(10)      NOT NULL,',
  1074.               ' zip         char(10)      NOT NULL,',
  1075.               ' DEPT        INTEGER       NOT NULL,',
  1076.               ' JOB         CHAR(75)      NOT NULL,',
  1077.               ' YEARS       decimal(4,2)  NOT NULL,',
  1078.               ' SALARY      DECIMAL(7,2)  NOT NULL,',
  1079.               ' COMM        DECIMAL(7,2)  NOT NULL)'
  1080.     table2 = 'CREATE TABLE FRDEMO.DEPARTMENT',
  1081.               '(DEPT        INTEGER       NOT NULL,',
  1082.               ' DEPTNAME    CHAR(75)      NOT NULL,',
  1083.               ' address1    CHAR(75)      NOT NULL,',
  1084.               ' address2    CHAR(75)      NOT NULL,',
  1085.               ' address3    CHAR(75)      NOT NULL,',
  1086.               ' address4    CHAR(75)      NOT NULL,',
  1087.               ' state       CHAR(10)      NOT NULL,',
  1088.               ' zip         char(10)      NOT NULL,',
  1089.               ' MANAGER     integer       NOT NULL,',
  1090.               ' DIVISION    INTEGER       NOT NULL,',
  1091.               ' LOCATION    CHAR(75)      NOT NULL)'
  1092.     table3 = 'CREATE TABLE FRDEMO.DIVISION',
  1093.               '(DIVISION    INTEGER       NOT NULL,',
  1094.               ' MANAGER     integer       NOT NULL,',
  1095.               ' DIRECTORATE INTEGER       NOT NULL,',
  1096.               ' DIVNAME     CHAR(75)      NOT NULL,',
  1097.               ' address1    CHAR(75)      NOT NULL,',
  1098.               ' address2    CHAR(75)      NOT NULL,',
  1099.               ' address3    CHAR(75)      NOT NULL,',
  1100.               ' address4    CHAR(75)      NOT NULL,',
  1101.               ' state       CHAR(10)      NOT NULL,',
  1102.               ' zip         char(10)      NOT NULL)'
  1103.     table4 = 'CREATE TABLE FRDEMO.DIRECTORATE',
  1104.               '(DIRECTORATE INTEGER       NOT NULL,',
  1105.               ' DIRECTOR    integer       NOT NULL,',
  1106.               ' DIRNAME     CHAR(75)      NOT NULL,',
  1107.               ' address1    CHAR(75)      NOT NULL,',
  1108.               ' address2    CHAR(75)      NOT NULL,',
  1109.               ' address3    CHAR(75)      NOT NULL,',
  1110.               ' address4    CHAR(75)      NOT NULL,',
  1111.               ' state       CHAR(10)      NOT NULL,',
  1112.               ' zip         char(10)      NOT NULL)'
  1113.  
  1114.     call Connect
  1115.  
  1116.     call TimingsBegin
  1117.     say c.itblue  '     CREATE TABLE EMPLOYEE'
  1118.     step = 'CREATE TABLE EMPLOYEE'
  1119.     call SQLEXEC 'EXECUTE IMMEDIATE :table1'
  1120.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1121.     call TimingsEnd
  1122.  
  1123.     call TimingsBegin
  1124.     say c.itblue  '     CREATE TABLE DEPARTMENT'
  1125.     step = 'CREATE TABLE DEPARTMENT'
  1126.     call SQLEXEC 'EXECUTE IMMEDIATE :table2'
  1127.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1128.     call TimingsEnd
  1129.  
  1130.     call TimingsBegin
  1131.     say c.itblue  '     CREATE TABLE DIVISION'
  1132.     step = 'CREATE TABLE DIVISION'
  1133.     call SQLEXEC 'EXECUTE IMMEDIATE :table3'
  1134.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1135.     call TimingsEnd
  1136.  
  1137.     call TimingsBegin
  1138.     say c.itblue  '     CREATE TABLE DIRECTORATE'
  1139.     step = 'CREATE TABLE DIRECTORATE'
  1140.     call SQLEXEC 'EXECUTE IMMEDIATE :table4'
  1141.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1142.     call TimingsEnd
  1143.  
  1144.     call ConnectReset
  1145.  
  1146.     return
  1147.  
  1148.  
  1149. CreateIndexes:
  1150. /*
  1151.  ┌──────────────────────────────────────────────────────────────────┐
  1152.  │    CreateIndexes                                                 │
  1153.  │                                                                  │
  1154.  │    Indexes don't have any direct bearing on this test, however,  │
  1155.  │    they are added for realism and for testing the effect of      │
  1156.  │    indexes and index changes to the log files.                   │
  1157.  │                                                                  │
  1158.  └──────────────────────────────────────────────────────────────────┘
  1159. */
  1160.     say c.itgreen '---> CREATE application table INDEXs'
  1161.  
  1162.     indexa = 'CREATE INDEX FRDEMO.DEPARTMENT_DEPT_I',
  1163.                 ' ON FRDEMO.DEPARTMENT',
  1164.                 ' (DEPT ASC)'
  1165.     indexb = 'CREATE INDEX FRDEMO.EMPLOYEE_SALARY_I',
  1166.                 ' ON FRDEMO.EMPLOYEE',
  1167.                 ' (SALARY ASC)'
  1168.     indexc = 'CREATE INDEX FRDEMO.EMPLOYEE_ID_I',
  1169.                 ' ON FRDEMO.EMPLOYEE',
  1170.                 ' (ID ASC)'
  1171.     indexd = 'CREATE INDEX FRDEMO.DIVISION_I',
  1172.                 ' ON FRDEMO.DIVISION',
  1173.                 ' (DIVISION ASC)'
  1174.     indexe = 'CREATE INDEX FRDEMO.DIRECTORATE_I',
  1175.                 ' ON FRDEMO.DIRECTORATE',
  1176.                 ' (DIRECTORATE ASC)'
  1177.  
  1178.     call Connect
  1179.  
  1180.     say c.itblue  '     CREATE INDEX DEPARTMENT_DEPT_I'
  1181.     step = 'CREATE INDEX DEPARTMENT_DEPT_I'
  1182.     call SQLEXEC 'EXECUTE IMMEDIATE :indexa'
  1183.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1184.  
  1185.     say c.itblue  '     CREATE INDEX EMPLOYEE_SALARY_I'
  1186.     step = 'CREATE INDEX EMPLOYEE_SALARY_I'
  1187.     call SQLEXEC 'EXECUTE IMMEDIATE :indexb'
  1188.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1189.  
  1190.     say c.itblue  '     CREATE INDEX EMPLOYEE_ID_I'
  1191.     step = 'CREATE INDEX EMPLOYEE_ID_I'
  1192.     call SQLEXEC 'EXECUTE IMMEDIATE :indexc'
  1193.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1194.  
  1195.     say c.itblue  '     CREATE INDEX DIVISION_I'
  1196.     step = 'CREATE INDEX DIVISION_I'
  1197.     call SQLEXEC 'EXECUTE IMMEDIATE :indexd'
  1198.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1199.  
  1200.     say c.itblue  '     CREATE INDEX DIRECTORATE_I'
  1201.     step = 'CREATE INDEX DIRECTORATE_I'
  1202.     call SQLEXEC 'EXECUTE IMMEDIATE :indexe'
  1203.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1204.  
  1205.     call ConnectReset
  1206.  
  1207.     return
  1208.  
  1209.  
  1210. DropFRDEMO:
  1211. /*
  1212.  ┌──────────────────────────────────────────────────────────────────┐
  1213.  │    DropFRDEMO                                                    │
  1214.  │                                                                  │
  1215.  │    Drop the database                                             │
  1216.  │                                                                  │
  1217.  └──────────────────────────────────────────────────────────────────┘
  1218. */
  1219.     say c.itgreen '     ---> Drop database' DBname
  1220.     step = 'drop the database'
  1221.     call SQLDBS 'DROP DATABASE' DBname
  1222.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1223.  
  1224.     return
  1225.  
  1226.  
  1227. DropTables:
  1228. /*
  1229.  ┌──────────────────────────────────────────────────────────────────┐
  1230.  │    DropTables                                                    │
  1231.  │                                                                  │
  1232.  │    Drop all tables                                               │
  1233.  │                                                                  │
  1234.  └──────────────────────────────────────────────────────────────────┘
  1235. */
  1236.     say c.itgreen '     ---> Drop all tables'
  1237.     say c.itblue  '     DROP table EMPLOYEE'
  1238.  
  1239.     call Connect
  1240.  
  1241.     step = 'DROP TABLE EMPLOYEE'
  1242.     stmtbuf = 'DROP TABLE FRDEMO.EMPLOYEE'
  1243.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1244.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1245.  
  1246.     say c.itblue  '     DROP table DEPARTMENT'
  1247.     step = 'DROP TABLE DEPARTMENT'
  1248.     stmtbuf = 'DROP TABLE FRDEMO.DEPARTMENT'
  1249.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1250.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1251.  
  1252.     say c.itblue  '     DROP table DIVISION'
  1253.     step = 'DROP TABLE DIVISION'
  1254.     stmtbuf = 'DROP TABLE FRDEMO.DIVISION'
  1255.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1256.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1257.  
  1258.     say c.itblue  '     DROP table DIRECTORATE'
  1259.     step = 'DROP TABLE DIRECTORATE'
  1260.     stmtbuf = 'DROP TABLE FRDEMO.DIRECTORATE'
  1261.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1262.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1263.  
  1264.     call ConnectReset
  1265.  
  1266.     return
  1267.  
  1268.  
  1269. DropIndexes:
  1270. /*
  1271.  ┌──────────────────────────────────────────────────────────────────┐
  1272.  │    DropIndexes                                                   │
  1273.  │                                                                  │
  1274.  │    Drop all indexes                                              │
  1275.  │                                                                  │
  1276.  └──────────────────────────────────────────────────────────────────┘
  1277. */
  1278.     say c.itgreen '     ---> Drop all indexes'
  1279.  
  1280.     call Connect
  1281.  
  1282.     step = 'DROP INDEX DEPARTMENT_DEPT_I'
  1283.     stmtbuf = 'DROP INDEX FRDEMO.DEPARTMENT_DEPT_I'
  1284.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1285.     if SQLCA.SQLCODE = -204 then say c.itblue  '     (index was undefined)'
  1286.     else
  1287.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1288.  
  1289.     step = 'DROP INDEX EMPLOYEE_SALARY_I'
  1290.     stmtbuf = 'DROP INDEX FRDEMO.EMPLOYEE_SALARY_I'
  1291.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1292.     if SQLCA.SQLCODE = -204 then say c.itblue  '     (index was undefined)'
  1293.     else
  1294.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1295.  
  1296.     step = 'DROP INDEX EMPLOYEE_ID_I'
  1297.     stmtbuf = 'DROP INDEX FRDEMO.EMPLOYEE_ID_I'
  1298.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1299.     if SQLCA.SQLCODE = -204 then say c.itblue  '     (index was undefined)'
  1300.     else
  1301.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1302.  
  1303.     step = 'DROP INDEX DIVISION_I'
  1304.     stmtbuf = 'DROP INDEX FRDEMO.DIVISION_I'
  1305.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1306.     if SQLCA.SQLCODE = -204 then say c.itblue  '     (index was undefined)'
  1307.     else
  1308.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1309.  
  1310.     step = 'DROP INDEX DIRECTORATE_I'
  1311.     stmtbuf = 'DROP INDEX FRDEMO.DIRECTORATE_I'
  1312.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1313.     if SQLCA.SQLCODE = -204 then say c.itblue  '     (index was undefined)'
  1314.     else
  1315.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1316.  
  1317.     call ConnectReset
  1318.  
  1319.     return
  1320.  
  1321.  
  1322.  
  1323. PopulateDirectorate:
  1324.     step = 'Populate Directorate'
  1325.     PopulateTable = 'FRDEMO.DIRECTORATE'
  1326.     call PopulateCounts
  1327.     PopulateCounter = 0
  1328.  
  1329.     call PrePopulateInserts
  1330.  
  1331.     do i = 1 to PopulateRowCount
  1332.         directorate = i
  1333.         directorate = directorate + 100000000
  1334.  
  1335.         director = RANDOM(1,100000)
  1336.         director  = director + 100000000
  1337.  
  1338.         interpret 'row = directorate||comma||director||comma||dirname||comma||address'
  1339.         interpret 'stmtbuf = stmt||rparen||row||lparen'
  1340.  
  1341.         call PopulateInsert
  1342.         If FatalInsert = 'Y' then return
  1343.     end
  1344.  
  1345.     call PostPopulateInserts
  1346.  
  1347.     return
  1348.  
  1349.  
  1350. PopulateDepartment:
  1351.     step = 'Populate Department'
  1352.     PopulateTable = 'FRDEMO.DEPARTMENT'
  1353.     call PopulateCounts
  1354.     PopulateCounter = 0
  1355.  
  1356.     call PrePopulateInserts
  1357.  
  1358.     do i = 1 to PopulateRowCount
  1359.         department = i
  1360.         department = department + 100000000
  1361.  
  1362.         manager  = RANDOM(1,100000)
  1363.         division = RANDOM(1,100000)
  1364.         manager  = manager  + 100000000
  1365.         division = division + 100000000
  1366.  
  1367.         interpret 'row = department||comma||deptname||comma||address||comma||manager||comma||division||comma||location'
  1368.         interpret 'stmtbuf = stmt||rparen||row||lparen'
  1369.  
  1370.         call PopulateInsert
  1371.         If FatalInsert = 'Y' then return
  1372.     end
  1373.  
  1374.     call PostPopulateInserts
  1375.  
  1376.     return
  1377.  
  1378.  
  1379. PopulateDivision:
  1380.     step = 'Populate Division'
  1381.     PopulateTable = 'FRDEMO.DIVISION'
  1382.     call PopulateCounts
  1383.     PopulateCounter = 0
  1384.  
  1385.     call PrePopulateInserts
  1386.  
  1387.     do i = 1 to PopulateRowCount
  1388.         division = i
  1389.         division = division + 100000000
  1390.  
  1391.         manager      = RANDOM(1,100000)
  1392.         directorate  = RANDOM(1,100000)
  1393.         manager      = manager  + 100000000
  1394.         directorate  = directorate + 100000000
  1395.  
  1396.         interpret 'row = division||comma||manager||comma||directorate||comma||divname||comma||address'
  1397.         interpret 'stmtbuf = stmt||rparen||row||lparen'
  1398.  
  1399.         call PopulateInsert
  1400.         If FatalInsert = 'Y' then return
  1401.     end
  1402.  
  1403.     call PostPopulateInserts
  1404.  
  1405.     return
  1406.  
  1407.  
  1408. PopulateEmployee:
  1409.     step = 'Populate Employee'
  1410.     PopulateTable = 'FRDEMO.EMPLOYEE'
  1411.     call PopulateCounts
  1412.     PopulateCounter = 0
  1413.  
  1414.     call PrePopulateInserts
  1415.  
  1416.     do i = 1 to PopulateRowCount
  1417.         id = i
  1418.         id = id + 100000000
  1419.         if id < 100025000 then
  1420.            job = "'MSR'"
  1421.         else
  1422.            job = "'AMSR'"
  1423.  
  1424.         years  = RANDOM(1,25)
  1425.         salary = RANDOM(10000,99000)
  1426.         comm   = RANDOM(0,5000)
  1427.         department = RANDOM(0,100000)
  1428.         department = department + 100000000
  1429.  
  1430.         interpret 'row = id||comma||detail||comma||department||comma||job||comma||years||comma||plus||salary||comma||plus||comm'
  1431.         interpret 'stmtbuf = stmt||rparen||row||lparen'
  1432.  
  1433.         call PopulateInsert
  1434.         if FatalInsert = 'Y' then return
  1435.  
  1436.     end
  1437.  
  1438.     call PostPopulateInserts
  1439.  
  1440.     return
  1441.  
  1442.  
  1443. PopulateInsert:
  1444. /*
  1445.  ┌──────────────────────────────────────────────────────────────────┐
  1446.  │    PopulateInsert                                                │
  1447.  │                                                                  │
  1448.  │    Execute the INSERT statement;  check the commit count         │
  1449.  │    to see if it's time to COMMIT or ROLLBACK.                    │
  1450.  │                                                                  │
  1451.  └──────────────────────────────────────────────────────────────────┘
  1452. */
  1453.     step = stmtbuf
  1454.     call SQLEXEC 'EXECUTE IMMEDIATE :stmtbuf'
  1455.     if SQLCA.SQLCODE = -204 then
  1456.         do
  1457.             say
  1458.             say c.itred 'Tables do not exist yet!'
  1459.             FatalInsert = 'Y'
  1460.             say c.itred 'press <enter> to continue'
  1461.             nimnull = SysGetKey('NOECHO')
  1462.             return
  1463.         end
  1464.     else
  1465.         if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1466.  
  1467.     PopulateCounter = PopulateCounter + 1
  1468.  
  1469.     if PopulateCounter = PopulateCommitCount then
  1470.         do
  1471.             tod = time()
  1472.             say c.itblue '     'PopulateOption c.itgreen tod 'after row 'i
  1473.             step = 'commit/rollback an insert'
  1474.             call SQLEXEC PopulateOption
  1475.             if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1476.  
  1477.             PopulateCounter = 0
  1478.         end
  1479.  
  1480.     return
  1481.  
  1482.  
  1483. PrePopulateInserts:
  1484. /*
  1485.  ┌──────────────────────────────────────────────────────────────────┐
  1486.  │    PrePopulateInserts:                                           │
  1487.  │                                                                  │
  1488.  │    Display banner, setup the host variable "stmt".               │
  1489.  │                                                                  │
  1490.  │    Get and save the beginning times.                             │
  1491.  │                                                                  │
  1492.  │    Start Using the database.                                     │
  1493.  │                                                                  │
  1494.  └──────────────────────────────────────────────────────────────────┘
  1495. */
  1496.     stmt = 'INSERT INTO' PopulateTable 'VALUES '
  1497.  
  1498.     say
  1499.     say c.itmagenta '---> INSERT' PopulateRowCount 'rows'
  1500.     say c.itmagenta '     'PopulateOption' every' PopulateCommitCount 'rows'
  1501.  
  1502.     FatalInsert = 'N'
  1503.     call Connect
  1504.  
  1505.     call TimingsBegin
  1506.  
  1507.     return
  1508.  
  1509.  
  1510. PostPopulateInserts:
  1511. /*
  1512.  ┌──────────────────────────────────────────────────────────────────┐
  1513.  │    PostPopulateInserts:                                          │
  1514.  │                                                                  │
  1515.  │    Calculate ending time for the inserts.                        │
  1516.  │                                                                  │
  1517.  │    Display stats. While these don't have anything to do with     │
  1518.  │  Forward Recovery, they might be useful to demonstrate the       │
  1519.  │  typical time that INSERTs takes (keeping in mind that a lot     │
  1520.  │  time is spent in this program building the INSERT string).      │
  1521.  │                                                                  │
  1522.  │    CONNECT RESET the database                                    │
  1523.  │                                                                  │
  1524.  └──────────────────────────────────────────────────────────────────┘
  1525. */
  1526.  
  1527.     call ConnectReset
  1528.  
  1529.     call TimingsEnd
  1530.  
  1531.     return
  1532.  
  1533.  
  1534. PopulateCounts:
  1535. /*
  1536.  ┌──────────────────────────────────────────────────────────────────┐
  1537.  │    PopulateCounts                                                │
  1538.  │                                                                  │
  1539.  │    Get the number of rows to INSERT, call PopulateOptionEdit     │
  1540.  │  to decide whether to COMMIT or ROLLBACK, and enter the count    │
  1541.  │  for COMMITting or ROLLBACKing.                                  │
  1542.  │                                                                  │
  1543.  └──────────────────────────────────────────────────────────────────┘
  1544. */
  1545.     say
  1546.     say c.yellow  '---> Populate' PopulateTable
  1547.     say
  1548.  
  1549.     say c.itgreen '     Enter number of rows to INSERT:'
  1550.     pull PopulateRowCount
  1551.  
  1552.     call PopulateOptionEdit
  1553.  
  1554.     say c.itgreen '     Enter # of rows to 'PopulateOption' at:'
  1555.     pull PopulateCommitCount
  1556.  
  1557.     return
  1558.  
  1559.  
  1560. PopulateOptionEdit:
  1561. /*
  1562.  ┌──────────────────────────────────────────────────────────────────┐
  1563.  │    PopulateOptionEdit                                            │
  1564.  │                                                                  │
  1565.  │    Get and edit the PopulateOption. Valid values are either      │
  1566.  │  COMMIT or ROLLBACK. This gives the user the option of running   │
  1567.  │  the INSERTs either way, generating log files in any case,       │
  1568.  │  and saving some disk space if the choice is ROLLBACK.           │
  1569.  │                                                                  │
  1570.  └──────────────────────────────────────────────────────────────────┘
  1571. */
  1572.     PopulateOption = 'COMMIT'
  1573.  
  1574.     say c.itgreen '     Transact <C>ommit or <R>ollback ?'
  1575.     PopulateOpt = SysGetKey('NOECHO')
  1576.  
  1577.     if PopulateOpt = 'C' | PopulateOpt = 'c' then
  1578.         PopulateOption = 'COMMIT'
  1579.     else
  1580.       if PopulateOpt = 'R' | PopulateOpt = 'r' then
  1581.           PopulateOption = 'ROLLBACK'
  1582.     else
  1583.       do
  1584.         say c.itred   '---> Invalid Option: reenter'
  1585.         signal PopulateOptionEdit
  1586.       end
  1587.  
  1588.     return
  1589.  
  1590.  
  1591.  
  1592.  
  1593. TimingsBegin:
  1594. /*
  1595.  ┌──────────────────────────────────────────────────────────────────┐
  1596.  │    TimingsBegin                                                  │
  1597.  │                                                                  │
  1598.  │    Get time and date for begin of a timed perf test              │
  1599.  │                                                                  │
  1600.  └──────────────────────────────────────────────────────────────────┘
  1601. */
  1602.  
  1603.     if OptionTiming = 'Y' then
  1604.         do
  1605.             start_tod = time()
  1606.             start_day = date('w')
  1607.             start_date = date()
  1608.         end
  1609.  
  1610.     return
  1611.  
  1612.  
  1613. TimingsEnd:
  1614. /*
  1615.  ┌──────────────────────────────────────────────────────────────────┐
  1616.  │    TimingsEnd                                                    │
  1617.  │                                                                  │
  1618.  │    Get time and date for the end of a timed perf test            │
  1619.  │    Display stats                                                 │
  1620.  │                                                                  │
  1621.  └──────────────────────────────────────────────────────────────────┘
  1622. */
  1623.     if OptionTiming = 'Y' then
  1624.         do
  1625.             end_tod = time()
  1626.             end_day = date('w')
  1627.             end_date = date()
  1628.  
  1629.             say c.itmagenta '---> Timings:'
  1630.             say c.itmagenta '     Began' start_tod 'on' start_day start_date
  1631.             say c.itmagenta '     Ended' end_tod 'on' end_day end_date
  1632.             pause
  1633.         end
  1634.  
  1635.     return
  1636.  
  1637.  
  1638. ProgramInitialize:
  1639. /*
  1640.  ┌──────────────────────────────────────────────────────────────────┐
  1641.  │    ProgramInitialize                                             │
  1642.  │                                                                  │
  1643.  │    Register all the RexxUtil calls                               │
  1644.  │                                                                  │
  1645.  │    Setup all of the variables used in the program, also calls    │
  1646.  │  the SetColor routine to setup colors.                           │
  1647.  │                                                                  │
  1648.  └──────────────────────────────────────────────────────────────────┘
  1649. */
  1650.     call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  1651.     call RxFuncAdd 'SQLDBS','SQLAR','SQLDBS'
  1652.     call RxFuncAdd 'SQLEXEC','SQLAR','SQLEXEC'
  1653.     call SysLoadFuncs
  1654.     address cmd '@ECHO OFF'
  1655.  
  1656.     call SetColor
  1657.  
  1658.     ConnectFlag = 'N'
  1659.     OptionTiming = 'N'
  1660.  
  1661.     COMMA        = ','
  1662.     RPAREN       = '('
  1663.     LPAREN       = ')'
  1664.     QUOTE        = "'"
  1665.     PLUS         = '+'
  1666.     ROW          = ' '
  1667.  
  1668.     DBdrive      = 'D'
  1669.     DBname       = 'FRDEMO'
  1670.  
  1671.     PopulateCommitCount = 0
  1672.  
  1673.     id           = 0
  1674.     years        = 0
  1675.     salary       = 0
  1676.     comm         = 0
  1677.     manager      = 0
  1678.     director     = 0
  1679.     department   = 0
  1680.     division     = 0
  1681.     directorate  = 0
  1682.     name         = "'Name'"
  1683.     address1     = "'IBM at Southlake'"
  1684.     address2     = "'40-A2-04'"
  1685.     address3     = "'1 East Kirkwood Blvd'"
  1686.     address4     = "'Roanoke'"
  1687.     state        = "'Texas'"
  1688.     zip          = "'76299-0015'"
  1689.     interpret 'address = address1||comma||address2||comma||address3||comma||address4||comma||state||comma||zip'
  1690.     interpret 'detail = name||comma||address'
  1691.     job          = "'Position'"
  1692.     deptname     = "'Department'"
  1693.     location     = "'IBM, Dallas System Center'"
  1694.     divname      = "'Personal System Support Center'"
  1695.     dirname      = "'Marketing and Technical Support'"
  1696.  
  1697.     return
  1698.  
  1699.  
  1700. StopDBM:
  1701. /*
  1702.  ┌──────────────────────────────────────────────────────────────────┐
  1703.  │    StopDBM                                                       │
  1704.  │                                                                  │
  1705.  │    Stops the Database Manager.                                   │
  1706.  │                                                                  │
  1707.  └──────────────────────────────────────────────────────────────────┘
  1708. */
  1709.     say c.itblue  '     STOP DB2/2'
  1710.     step = 'stop database manager'
  1711.  
  1712.     CALL SQLDBS 'STOP DATABASE MANAGER'
  1713.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1714.  
  1715.     return
  1716.  
  1717.  
  1718. StartDBM:
  1719. /*
  1720.  ┌──────────────────────────────────────────────────────────────────┐
  1721.  │    StartDBM                                                      │
  1722.  │                                                                  │
  1723.  │    Starts the Database Manager.                                  │
  1724.  │                                                                  │
  1725.  └──────────────────────────────────────────────────────────────────┘
  1726. */
  1727.     say c.itblue  '     START DB2/2'
  1728.     step = 'start database manager'
  1729.  
  1730.     CALL SQLDBS 'START DATABASE MANAGER'
  1731.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1732.  
  1733.     return
  1734.  
  1735.  
  1736. Connect:
  1737. /*
  1738.  ┌──────────────────────────────────────────────────────────────────┐
  1739.  │    Connect                                                       │
  1740.  │                                                                  │
  1741.  │    Does a CONNECT to the database in question                    │
  1742.  │                                                                  │
  1743.  └──────────────────────────────────────────────────────────────────┘
  1744. */
  1745.     step = 'CONNECT'
  1746.  
  1747.     say c.itblue  '     CONNECT'
  1748.     call SQLEXEC 'CONNECT TO' DBname 'IN SHARED MODE'
  1749.     if SQLCA.SQLCODE = 0 then
  1750.         do
  1751.             ConnectFlag = 'Y'
  1752.             return
  1753.         end
  1754.     else signal ErrorSQL
  1755.  
  1756.     return
  1757.  
  1758.  
  1759. ConnectReset:
  1760. /*
  1761.  ┌──────────────────────────────────────────────────────────────────┐
  1762.  │    ConnectReset                                                  │
  1763.  │                                                                  │
  1764.  │    Does a CONNECT RESET                                          │
  1765.  │                                                                  │
  1766.  └──────────────────────────────────────────────────────────────────┘
  1767. */
  1768.     step = 'CONNECT RESET'
  1769.  
  1770.     ConnectFlag = 'N'
  1771.  
  1772.     say c.itblue  '     CONNECT RESET'
  1773.     say c.itblue
  1774.     call SQLEXEC 'CONNECT RESET'
  1775.     if SQLCA.SQLCODE \= 0 then signal ErrorSQL
  1776.  
  1777.     return
  1778.  
  1779.  
  1780. EndProg:
  1781. /*
  1782.  ┌──────────────────────────────────────────────────────────────────┐
  1783.  │    EndProg                                                       │
  1784.  │                                                                  │
  1785.  │    Check to see if a START USING had been done - if so then      │
  1786.  │  do a STOP USING so that the program can be immediately rerun    │
  1787.  │  from the same window. Also reset the colors.                    │
  1788.  │                                                                  │
  1789.  └──────────────────────────────────────────────────────────────────┘
  1790. */
  1791.     if ConnectFlag = 'Y' then
  1792.         do
  1793.             call ConnectReset
  1794.         end
  1795.  
  1796.     say c.reset
  1797.  
  1798.     'exit'
  1799.  
  1800.  
  1801. ErrorSQL:
  1802. /*
  1803.  ┌──────────────────────────────────────────────────────────────────┐
  1804.  │    ErrorSQL                                                      │
  1805.  │                                                                  │
  1806.  │    SQL Error routine - handles fatal SQL errors.                 │
  1807.  │                                                                  │
  1808.  └──────────────────────────────────────────────────────────────────┘
  1809. */
  1810.     tod = time()
  1811.     call beep 100,200
  1812.     say c.itred
  1813.     say 'SQLCODE' SQLCA.SQLCODE 'at step:' step
  1814.     say '     SQLERRP       = ' SQLCA.SQLERRP
  1815.     SAY '     SQLERRD 1  2  = ' SQLCA.SQLERRD.1 ' ' SQLCA.SQLERRD.2
  1816.     SAY '             3  4  = ' SQLCA.SQLERRD.3 ' ' SQLCA.SQLERRD.4
  1817.     SAY '             5  6  = ' SQLCA.SQLERRD.5 ' ' SQLCA.SQLERRD.6
  1818.     SAY '     SQLWARN 0  1  = ' SQLCA.SQLWARN.0 ' ' SQLCA.SQLWARN.1
  1819.     SAY '             2  3  = ' SQLCA.SQLWARN.2 ' ' SQLCA.SQLWARN.3
  1820.     SAY '             4  5  = ' SQLCA.SQLWARN.4 ' ' SQLCA.SQLWARN.5
  1821.     SAY '             6  7  = ' SQLCA.SQLWARN.6 ' ' SQLCA.SQLWARN.7
  1822.     SAY '             8  9  = ' SQLCA.SQLWARN.8 ' ' SQLCA.SQLWARN.9
  1823.     SAY '             10    = ' SQLCA.SQLWARN.10
  1824.     say '     SQLSTATE      = ' SQLCA.SQLSTATE
  1825.     say '     text message  = ' SQLMSG
  1826.     say
  1827.     pause
  1828.     signal EndProg
  1829.  
  1830.  
  1831.  
  1832.  
  1833. SoftErrorSQL:
  1834. /*
  1835.  ┌──────────────────────────────────────────────────────────────────┐
  1836.  │    SoftErrorSQL                                                  │
  1837.  │                                                                  │
  1838.  │    SQL Error routine - handles soft (handleable) SQL errors      │
  1839.  │                                                                  │
  1840.  └──────────────────────────────────────────────────────────────────┘
  1841. */
  1842.     tod = time()
  1843.     call beep 100,200
  1844.     say c.red
  1845.     say 'SQLCODE' SQLCA.SQLCODE 'at step:' step
  1846.     say '     SQLERRP       = ' SQLCA.SQLERRP
  1847.     SAY '     SQLERRD 1  2  = ' SQLCA.SQLERRD.1 ' ' SQLCA.SQLERRD.2
  1848.     SAY '             3  4  = ' SQLCA.SQLERRD.3 ' ' SQLCA.SQLERRD.4
  1849.     SAY '             5  6  = ' SQLCA.SQLERRD.5 ' ' SQLCA.SQLERRD.6
  1850.     SAY '     SQLWARN 0  1  = ' SQLCA.SQLWARN.0 ' ' SQLCA.SQLWARN.1
  1851.     SAY '             2  3  = ' SQLCA.SQLWARN.2 ' ' SQLCA.SQLWARN.3
  1852.     SAY '             4  5  = ' SQLCA.SQLWARN.4 ' ' SQLCA.SQLWARN.5
  1853.     SAY '             6  7  = ' SQLCA.SQLWARN.6 ' ' SQLCA.SQLWARN.7
  1854.     SAY '             8  9  = ' SQLCA.SQLWARN.8 ' ' SQLCA.SQLWARN.9
  1855.     SAY '             10    = ' SQLCA.SQLWARN.10
  1856.     say '     SQLSTATE      = ' SQLCA.SQLSTATE
  1857.     say '     text message  = ' SQLMSG
  1858.     say
  1859.     say 'press <enter> to continue'
  1860.     nullinput = SysGetKey('NOECHO')
  1861.     say c.normal
  1862.     return
  1863.  
  1864.  
  1865. ErrorRC:
  1866. /*
  1867.  ┌──────────────────────────────────────────────────────────────────┐
  1868.  │    ErrorRC                                                       │
  1869.  │                                                                  │
  1870.  │    RC Error routine - handles CMD.EXE return code                │
  1871.  │                                                                  │
  1872.  └──────────────────────────────────────────────────────────────────┘
  1873. */
  1874.     tod = time()
  1875.     call beep 100,200
  1876.     say c.itred
  1877.     say '        >>>  OS/2 has returned a fatal condition code'
  1878.     say '             abending step = ' step
  1879.     say '             source line   = ' sourceline(sigl)
  1880.     say '                      time = ' tod
  1881.     say '                        RC = ' RC
  1882.     say '                    RESULT = ' RESULT
  1883.     say
  1884.     pause
  1885.     signal EndProg
  1886.  
  1887.  
  1888. Error:
  1889. /*
  1890.  ┌──────────────────────────────────────────────────────────────────┐
  1891.  │    Error                                                         │
  1892.  │                                                                  │
  1893.  │    Rexx Error handling routine                                   │
  1894.  │                                                                  │
  1895.  └──────────────────────────────────────────────────────────────────┘
  1896. */
  1897.     tod = time()
  1898.     call beep 220,1000
  1899.     say c.itred
  1900.     say '        >>>  Rexx has returned a signal on error'
  1901.     say '             abending step = ' step
  1902.     say '             source line   = ' sourceline(sigl)
  1903.     say '                        RC = ' RC
  1904.     say '                      time = ' tod
  1905.     say
  1906.     pause
  1907.     signal EndProg
  1908.  
  1909.  
  1910. Syntax:
  1911. /*
  1912.  ┌──────────────────────────────────────────────────────────────────┐
  1913.  │    Syntax                                                        │
  1914.  │                                                                  │
  1915.  │    Rexx Error handling routine                                   │
  1916.  │                                                                  │
  1917.  └──────────────────────────────────────────────────────────────────┘
  1918. */
  1919.     call beep 220,1000
  1920.     say c.itred
  1921.     say '        >>>  Rexx has returned a signal on syntax'
  1922.     say '             abending step = ' step
  1923.     say '             source line   = ' sourceline(sigl)
  1924.     say
  1925.     pause
  1926.     signal EndProg
  1927.  
  1928.  
  1929. SetColor:
  1930. /*
  1931.  ┌──────────────────────────────────────────────────────────────────┐
  1932.  │    SetColor                                                      │
  1933.  │                                                                  │
  1934.  │    This paragragh sets the colors used in the program.           │
  1935.  │                                                                  │
  1936.  └──────────────────────────────────────────────────────────────────┘
  1937. */
  1938.     ansii.esc      = '1B'x
  1939.     c.normal       = ansii.esc || '[0m'
  1940.     c.highlite     = ansii.esc || '[1m'
  1941.     c.blackback    = ansii.esc || '[40m'
  1942.     c.green        = c.normal || ansii.esc || '[32m'
  1943.     c.grey         = c.normal || ansii.esc || '[37m'
  1944.     c.red          = c.normal || ansii.esc || '[31m'
  1945.     c.itred        = c.highlite || ansii.esc || '[31m'
  1946.     c.itgreen      = c.highlite || ansii.esc || '[32m'
  1947.     c.yellow       = c.highlite || ansii.esc || '[33m'
  1948.     c.itblue       = c.highlite || ansii.esc || '[34m'
  1949.     c.itmagenta    = c.highlite || ansii.esc || '[35m'
  1950.     c.itcyan       = c.highlite || ansii.esc || '[36m'
  1951.     c.white        = c.highlite || ansii.esc || '[37m'
  1952.     c.std          = c.normal || c.itcyan || c.blackback
  1953.     c.reset        = c.normal || c.grey || c.blackback
  1954.     return 0
  1955.