Initializing Data (BANKDATA)
The BANKDATA program is responsible for initializing and populating customer and account data in a simulated banking application. The program achieves this by setting up initial parameters, validating input, generating random customer data, and performing database operations to insert and delete records. The program also handles file operations and ensures data integrity through various validation and commit processes.
The BANKDATA program starts by initializing parameters and validating input. It then generates random customer data, including names, addresses, birth dates, and credit scores. The program writes this data to the CUSTOMER and ACCOUNT datastores, performs necessary database operations, and commits the records to ensure data integrity. Finally, it closes the files and logs the operations for tracking purposes.
Here is a high level diagram of the program:
Setup Initialization
Starting the PREMIERE Section
First, the PREMIERE
TIMESTAMP-FUNCTION
TIMESTAMP
PREMIERE SECTION.
A010.
MOVE 'Starting BANKDATA'
to TIMESTAMP-FUNCTION
perform TIMESTAMP
Logging the Start Time
The TIMESTAMP
PREMIERE
TIMESTAMP SECTION.
CALL 'CEEGMT' USING BY REFERENCE gmt-lilian
BY REFERENCE gmt-seconds
BY REFERENCE fc
***
*** Move gmt to an integer so that we don't round up
*** in the division
***
MOVE gmt-seconds TO period-next-f.
COMPUTE period-next = period-next-f.
***
*** Convert back into text
***
MOVE 14 TO datm-length.
MOVE 'YYYYMMDDHHMISS' TO datm-format.
CALL 'CEEDATM' USING BY REFERENCE period-next
BY REFERENCE datm-picture
BY REFERENCE datm-conv
BY REFERENCE fc.
Initializing Arrays
Next, a message 'About to initialise arrays' is displayed. The INITIALISE-ARRAYS
* Initialise the arrays
*
D DISPLAY 'About to initialise arrays'.
PERFORM INITIALISE-ARRAYS.
Setting Up Arrays
The INITIALISE-ARRAYS
INITIALISE-ARRAYS SECTION.
IA010.
MOVE TITLE-ALPHABET TO TITLE-WORDS.
MOVE 50 TO FORENAMES-CNT.
MOVE 'Michael' TO FORENAME(01).
MOVE 'Will' TO FORENAME(02).
MOVE 'Geoff' TO FORENAME(03).
MOVE 'Chris' TO FORENAME(04).
MOVE 'Dave' TO FORENAME(05).
MOVE 'Luke' TO FORENAME(06).
MOVE 'Adam' TO FORENAME(07).
MOVE 'Giuseppe' TO FORENAME(08).
MOVE 'James' TO FORENAME(09).
MOVE 'Jon' TO FORENAME(10).
MOVE 'Andy' TO FORENAME(11).
MOVE 'Lou' TO FORENAME(12).
MOVE 'Robert' TO FORENAME(13).
MOVE 'Sam' TO FORENAME(14).
Parameter Handling and Validation
Get Parameters
First, the parameters are extracted from the input string PARM
UNSTRING
START-KEY
END-KEY
STEP-KEY
RANDOM-SEED
* Get the parameters
*
UNSTRING PARM(1:PARM-LENGTH)
DELIMITED BY SPACE OR ','
INTO START-KEY
END-KEY
STEP-KEY
RANDOM-SEED.
Display Input Parameters
Next, the extracted parameters are displayed for verification. This helps in ensuring that the correct values have been parsed and are ready for further processing.
D DISPLAY 'INPUT PARMS ARE: START-KEY=' START-KEY
D ' END-KEY=' END-KEY ' STEP-KEY=' STEP-KEY
D ' RANDOM-SEED=' RANDOM-SEED '
Validate Parameters
Then, the parameters are validated. If END-KEY
START-KEY
STEP-KEY
IF END-KEY < START-KEY
MOVE 12 TO RETURN-CODE
DISPLAY 'Final customer number cannot be smaller than '
'first customer number'
GOBACK
END-IF
IF step-key = zero
MOVE 12 TO RETURN-CODE
DISPLAY 'Gap between customers cannot be zero'
GOBACK
END-IF
Get Today's Date
Moving to the next step, the current date is fetched and stored as an integer. This is done by performing the GET-TODAYS-DATE
* Get today's date and store it as an INTEGER
*
PERFORM GET-TODAYS-DATE.
GET-TODAYS-DATE
GET-TODAYS-DATE
The GET-TODAYS-DATE
CURRENT-DATE
WS-TODAY-INT
GET-TODAYS-DATE SECTION.
GTD010.
D DISPLAY 'IN GET-TODAYS-DATE SECTION'.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-DATA.
MOVE WS-CURRENT-DATE-DATA (1:8) TO WS-CURRENT-DATE-9.
COMPUTE WS-TODAY-INT =
FUNCTION INTEGER-OF-DATE (WS-CURRENT-DATE-9).
GTD999.
EXIT.
Interim Summary
So far, we saw how the program initializes by setting up timestamps and arrays, and then handles and validates input parameters. Now, we will focus on the process of deleting rows from the DB2
Date and Random Seed Initialization
Display 'About to delete DB2
rows'
DB2
First, we display a message indicating that the process of deleting DB2
D DISPLAY 'About to delete DB2 rows'.
Delete rows from ACCOUNT table
Moving to the DELETE-DB2-ROWS
ACCOUNT_SORTCODE
SortCode
DELETE-DB2-ROWS SECTION.
DBR010.
*
* Delete the ACCOUNT table data
*
MOVE SORTCODE TO HV-ACCOUNT-SORT-CODE.
MOVE 'Deleting from ACCOUNT table'
to TIMESTAMP-FUNCTION
perform TIMESTAMP
EXEC SQL
DELETE FROM ACCOUNT
WHERE ACCOUNT_SORTCODE = :HV-ACCOUNT-SORT-CODE
END-EXEC.
Check SQL code for ACCOUNT table
Next, we check the SQL code to ensure the deletion was successful. If the SQL code is not OK (0) or NOTFND (+100), we handle the error by displaying an appropriate message and setting the return code.
* Check the SQL code if it was NOT OK (0) or NOTFND (+100)
* then abend
*
MOVE 'Deleting from ACCOUNT table COMPLETE'
to TIMESTAMP-FUNCTION
perform TIMESTAMP
IF SQLCODE NOT = +100 AND
SQLCODE NOT = 0
MOVE SQLCODE TO DISP-SQLCD
IF SQLCODE < 0
MOVE '-' TO DISP-SIGN
ELSE
MOVE '+' TO DISP-SIGN
END-IF
EVALUATE TRUE
WHEN SQLERRD(3) EQUAL 13172878
MOVE 'TIMEOUT (00C900E)' TO DISP-REASON-CODE
WHEN SQLERRD(3) EQUAL 13172872
MOVE 'DEADLOCK (00C9088)' TO DISP-REASON-CODE
WHEN OTHER
Delete rows from CONTROL table - ACCOUNT-LAST
ACCOUNT-LAST
Then, we delete rows from the CONTROL table where the CONTROL_NAME
SortCode
ACCOUNT-LAST
* Delete the CONTROL table data
*
MOVE SPACES TO HV-CONTROL-NAME
STRING SORTCODE DELIMITED BY SIZE
'-' DELIMITED BY SIZE
'ACCOUNT-LAST' DELIMITED BY SIZE
INTO HV-CONTROL-NAME
MOVE 'Deleting from CONTROL table'
to TIMESTAMP-FUNCTION.
PERFORM TIMESTAMP.
EXEC SQL
DELETE FROM CONTROL
WHERE CONTROL_NAME = :HV-CONTROL-NAME
END-EXEC.
Check SQL code for CONTROL table - ACCOUNT-LAST
ACCOUNT-LAST
We again check the SQL code to ensure the deletion from the CONTROL table was successful. Similar to the previous check, we handle any errors by displaying messages and setting the return code.
* Check the SQL code if it was NOT OK (0) or NOTFND (+100)
* then abend
*
MOVE 'Deleting from CONTROL table COMPLETE'
to TIMESTAMP-FUNCTION.
PERFORM TIMESTAMP.
IF SQLCODE NOT = +100 AND
SQLCODE NOT = 0
MOVE SQLCODE TO DISP-SQLCD
IF SQLCODE < 0
MOVE '-' TO DISP-SIGN
ELSE
MOVE '+' TO DISP-SIGN
END-IF
EVALUATE TRUE
WHEN SQLERRD(3) EQUAL 13172878
MOVE 'TIMEOUT (00C900E)' TO DISP-REASON-CODE
WHEN SQLERRD(3) EQUAL 13172872
Delete rows from CONTROL table - ACCOUNT-COUNT
ACCOUNT-COUNT
Next, we delete rows from the CONTROL table where the CONTROL_NAME
SortCode
ACCOUNT-COUNT
*
MOVE SPACES TO HV-CONTROL-NAME
STRING SORTCODE DELIMITED BY SIZE
'-' DELIMITED BY SIZE
'ACCOUNT-COUNT' DELIMITED BY SIZE
INTO HV-CONTROL-NAME
MOVE 'Deleting from CONTROL table'
to TIMESTAMP-FUNCTION.
PERFORM TIMESTAMP.
EXEC SQL
DELETE FROM CONTROL
WHERE CONTROL_NAME = :HV-CONTROL-NAME
END-EXEC.
Check SQL code for CONTROL table - ACCOUNT-COUNT
ACCOUNT-COUNT
We perform another SQL code check to ensure the deletion from the CONTROL table was successful. Any errors are handled similarly by displaying messages and setting the return code.
* Check the SQL code if it was NOT OK (0) or NOTFND (+100)
* then abend
*
MOVE 'Deleting from CONTROL table COMPLETE'
to TIMESTAMP-FUNCTION.
PERFORM TIMESTAMP.
IF SQLCODE NOT = +100 AND
SQLCODE NOT = 0
MOVE SQLCODE TO DISP-SQLCD
IF SQLCODE < 0
MOVE '-' TO DISP-SIGN
ELSE
MOVE '+' TO DISP-SIGN
END-IF
EVALUATE TRUE
WHEN SQLERRD(3) EQUAL 13172878
MOVE 'TIMEOUT (00C900E)' TO DISP-REASON-CODE
WHEN SQLERRD(3) EQUAL 13172872
Commit work
Finally, we commit the work to ensure that all deletions are saved and the database is updated accordingly.
EXEC SQL
COMMIT WORK
END-EXEC.
Display 'Back from delete DB2
rows'
DB2
After completing the deletions and committing the work, we display a message indicating that the process of deleting DB2
D DISPLAY 'Back from delete DB2 rows'.
File Opening
This is the next section of the flow.
Opening the Customer File
First, the code attempts to open the CUSTOMER-FILE
OPEN OUTPUT CUSTOMER-FILE.
Handling File Open Errors
Next, the code checks if the CUSTOMER-VSAM-STATUS
RETURN-CODE
PROGRAM-DONE
IF CUSTOMER-VSAM-STATUS NOT EQUAL '00' THEN
DISPLAY 'Error opening CUSTOMER file, status='
CUSTOMER-VSAM-STATUS
MOVE 12 TO RETURN-CODE
PERFORM PROGRAM-DONE
END-IF.
Data Population Loop
Initialize Customer Data
First, we initialize the customer data by setting up the timestamp, commit count, and customer/account numbers. This sets the stage for generating new customer records.
* Populate the CUSTOMER file
*
MOVE 'Populating Customer + Account files'
to TIMESTAMP-FUNCTION
perform TIMESTAMP
MOVE ZERO TO COMMIT-COUNT
MOVE ZERO TO LAST-CUSTOMER-NUMBER NUMBER-OF-CUSTOMERS
MOVE ZERO TO LAST-ACCOUNT-NUMBER NUMBER-OF-ACCOUNTS
Generate Random Customer Data
Next, we loop through a range of keys to generate customer data. For each key, we initialize the customer record and set a unique customer number.
PERFORM TEST BEFORE
VARYING NEXT-KEY FROM START-KEY BY STEP-KEY
UNTIL NEXT-KEY > END-KEY
INITIALIZE CUSTOMER-RECORD IN CUSTOMER-RECORD-STRUCTURE
SET CUSTOMER-EYECATCHER-VALUE TO TRUE
MOVE NEXT-KEY TO CUSTOMER-NUMBER
MOVE NEXT-KEY TO LAST-CUSTOMER-NUMBER
ADD 1 TO NUMBER-OF-CUSTOMERS GIVING NUMBER-OF-CUSTOMERS
Generate Random Address
Then, we generate random values for the customer's title, forenames, initials, surname, house number, street names, and town. These values are combined to form the customer's name and address.
D DISPLAY 'Generating data for customer ' customer-number
COMPUTE TITLE-NUMBER = ((36 - 1)
* FUNCTION RANDOM) + 1
COMPUTE FORENAMES-PTR = ((FORENAMES-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE INITIALS-PTR = ((INITIALS-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE SURNAMES-PTR = ((SURNAMES-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE HOUSE-NUMBER = (99
* FUNCTION RANDOM) + 1
COMPUTE STREET-NAME-T-PTR = ((STREET-NAME-T-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE STREET-NAME-R-PTR = ((STREET-NAME-R-CNT - 1)
* FUNCTION RANDOM) + 1
COMPUTE TOWN-PTR = ((TOWN-COUNT - 1)
* FUNCTION RANDOM) + 1
MOVE SPACES TO CUSTOMER-NAME
Generate Random Birth Date
Moving to the next step, we generate a random birth date for the customer, ensuring the date is within a realistic range.
COMPUTE CUSTOMER-BIRTH-DAY = ((28 - 1)
* FUNCTION RANDOM) + 1
COMPUTE CUSTOMER-BIRTH-MONTH = ((12 - 1)
* FUNCTION RANDOM) + 1
COMPUTE CUSTOMER-BIRTH-YEAR = ((2000 - 1900)
* FUNCTION RANDOM) + 1900
Generate Random Credit Score
We then generate a random credit score for the customer, which will be used in later processes.
MOVE SORTCODE TO
CUSTOMER-SORTCODE
COMPUTE CUSTOMER-CREDIT-SCORE = ((999 - 1)
* FUNCTION RANDOM) + 1
Generate Review Date
Next, we generate a random review date for the customer's credit score, ensuring it falls within 1 to 21 days from the current date. This date is then formatted and stored in the customer record.
*
* Generate the random credit score review date. This
* should be a date between 1 and 21 days from today
*
COMPUTE WS-REVIEW-DATE-ADD = ((21 - 1)
* FUNCTION RANDOM) + 1
COMPUTE WS-NEW-REVIEW-DATE-INT =
WS-TODAY-INT + WS-REVIEW-DATE-ADD
*
* Convert the integer date back to YYYYMMDD format
* and store on the CUSTOMER record
*
COMPUTE WS-NEW-REVIEW-YYYYMMDD = FUNCTION
DATE-OF-INTEGER (WS-NEW-REVIEW-DATE-INT)
MOVE WS-NEW-REVIEW-YYYYMMDD(1:4) TO
CUSTOMER-CS-REVIEW-YEAR
Write Customer Record
We write the populated customer record to the CUSTOMER datastore.
WRITE CUSTOMER-RECORD-STRUCTURE
Check Write Status
We check the status of the write operation. If there is an error, we display an error message and perform the program termination routine.
IF CUSTOMER-VSAM-STATUS NOT EQUAL '00' THEN
DISPLAY 'Error writing to VSAM file, status='
CUSTOMER-VSAM-STATUS
MOVE 12 TO RETURN-CODE
PERFORM PROGRAM-DONE
END-IF
Populate Account Data
Having written the customer data, we now use some of this information to populate related data in the ACCOUNT datastore.
*
* Having written out to the CUSTOMER datastore we now need to
* use some of this information to populate related data on
* on the ACCOUNT datastore.
*
PERFORM DEFINE-ACC
Commit Records
Finally, we increment the commit count and commit the records to the database every 1,000
ADD 1 TO COMMIT-COUNT GIVING COMMIT-COUNT
IF COMMIT-COUNT > 1000
D DISPLAY 'Commit every 1,000 records or so'
EXEC SQL
COMMIT WORK
END-EXEC
MOVE ZERO TO COMMIT-COUNT
END-IF
Post-Population Operations
This is the next section of the flow.
Initialize Customer Control Number
First, the customer control number is initialized to '9999999999'. This sets a default value for the customer control record.
MOVE '9999999999' TO CUSTOMER-CONTROL-NUMBER
Set Control Eyecatcher
Moving to the next step, the control eyecatcher is set to true. This is likely used as a flag to indicate that the customer control record is active.
SET CUSTOMER-CONTROL-EYECATCHER-V TO TRUE
Display Write Message
Next, a message is displayed indicating that the customer control record is about to be written. This is useful for logging and debugging purposes.
D DISPLAY 'ABOUT TO WRITE CUSTOMER-CONTROL-RECORD'
Move Customer Control Record
Then, the customer control record is moved to the customer record structure. This prepares the data for writing to the file.
MOVE CUSTOMER-CONTROL-RECORD
TO CUSTOMER-RECORD IN CUSTOMER-RECORD-STRUCTURE
Write Customer Record Structure
The customer record structure is written to the file. This step persists the customer control record.
WRITE CUSTOMER-RECORD-STRUCTURE
Check VSAM Status
If the VSAM status is not '00', an error message is displayed, the return code is set to 12, and the program done routine is performed. This handles any errors that occur during the write operation.
IF CUSTOMER-VSAM-STATUS NOT EQUAL '00' THEN
DISPLAY 'Error writing CUSTOMER-CONTROL-RECORD file'
', status=' CUSTOMER-VSAM-STATUS
MOVE 12 TO RETURN-CODE
PERFORM PROGRAM-DONE
END-IF.
Move Spaces to Control Name
Moving to the next part, spaces are moved to the control name. This initializes the control name variable.
MOVE SPACES TO HV-CONTROL-NAME
Move Last Account Number
The last account number is moved to the control value number. This sets the value to be stored in the control record.
MOVE LAST-ACCOUNT-NUMBER TO HV-CONTROL-VALUE-NUM
Move Spaces to Control Value String
Spaces are moved to the control value string. This initializes the control value string variable.
MOVE SPACES TO HV-CONTROL-VALUE-STR
Create Control Name String
A string is created for the control name by concatenating the sort code, a hyphen, and ACCOUNT-LAST
STRING SORTCODE DELIMITED BY SIZE
'-' DELIMITED BY SIZE
'ACCOUNT-LAST' DELIMITED BY SIZE
INTO HV-CONTROL-NAME
Insert Last Account Control Record
An SQL insert statement is executed to insert the last account control record into the control table. This stores the last account number in the database.
EXEC SQL
INSERT INTO CONTROL
(CONTROL_NAME,
CONTROL_VALUE_NUM,
CONTROL_VALUE_STR
)
VALUES (:HV-CONTROL-NAME,
:HV-CONTROL-VALUE-NUM,
:HV-CONTROL-VALUE-STR
)
END-EXEC.
Check SQLCODE
If the SQLCODE is not zero, an error message is displayed. This handles any errors that occur during the insert operation.
IF SQLCODE IS NOT EQUAL TO ZERO
MOVE SQLCODE TO WS-SQLCODE-DISPLAY
DISPLAY 'Error inserting last account control record '
ws-sqlcode-display
'.'
HV-CONTROL-NAME,
','
HV-CONTROL-VALUE-NUM
END-IF
Move Spaces to Control Name
Moving to the next part, spaces are moved to the control name. This initializes the control name variable for the next insert operation.
MOVE SPACES TO HV-CONTROL-NAME
Move Number of Accounts
The number of accounts is moved to the control value number. This sets the value to be stored in the control record.
MOVE NUMBER-OF-ACCOUNTS TO HV-CONTROL-VALUE-NUM
Move Spaces to Control Value String
Spaces are moved to the control value string. This initializes the control value string variable.
MOVE SPACES TO HV-CONTROL-VALUE-STR
Create Control Name String
A string is created for the control name by concatenating the sort code, a hyphen, and ACCOUNT-COUNT
STRING SORTCODE DELIMITED BY SIZE
'-' DELIMITED BY SIZE
'ACCOUNT-COUNT' DELIMITED BY SIZE
INTO HV-CONTROL-NAME
Insert Account Count Control Record
An SQL insert statement is executed to insert the account count control record into the control table. This stores the number of accounts in the database.
EXEC SQL
INSERT INTO CONTROL
(CONTROL_NAME,
CONTROL_VALUE_NUM,
CONTROL_VALUE_STR
)
VALUES (:HV-CONTROL-NAME,
:HV-CONTROL-VALUE-NUM,
:HV-CONTROL-VALUE-STR
)
END-EXEC.
Check SQLCODE
If the SQLCODE is not zero, an error message is displayed. This handles any errors that occur during the insert operation.
IF SQLCODE IS NOT EQUAL TO ZERO
MOVE SQLCODE TO WS-SQLCODE-DISPLAY
DISPLAY 'Error inserting account count control record '
ws-sqlcode-display
'.'
HV-CONTROL-NAME,
','
HV-CONTROL-VALUE-NUM
END-IF
Closing and Final Timestamp
This is the next section of the flow.
Start Closing Files
This section begins the process of closing the files used in the banking application. It ensures that all files are properly closed after transactions are processed, maintaining data integrity and preventing data loss.
*
*** Close the files
*
Close BANKDATA File
The BANKDATA file, which contains customer and account information, is closed to ensure that all changes are saved and the file is not left in an open state, which could lead to data corruption.
CLOSE CUSTOMER-FILE.
MOVE 'Finishing BANKDATA'
to TIMESTAMP-FUNCTION
perform TIMESTAMP.
Close TRANSACTIONS File
The TRANSACTIONS file, which logs all the transactions processed during the session, is closed to ensure that all transaction records are properly saved and the file is secured.
A999.
EXIT.
*
End Closing Files
This marks the end of the file closing process, ensuring that all necessary files have been closed properly, and the system can safely proceed to the next steps or shut down.
* Finish
*
This is an auto-generated document by Swimm 🌊 and has not yet been verified by a human