94400d50d4
作为子目录纳入系统,与核心测试管道协同 Co-Authored-By: Claude <noreply@anthropic.com>
755 lines
29 KiB
COBOL
755 lines
29 KiB
COBOL
*> ============================================================
|
|
*> 23-select-condition : Customer Search (TELECOM BILLING)
|
|
*> Input : CUSTOMER-FILE (INDEXED)
|
|
*> Output: REPORT-FILE, TXN-LOG, AUDIT-FILE
|
|
*> Coverage: DB-N001, DB-N002, DB-N006, DB-R001
|
|
*> ============================================================
|
|
IDENTIFICATION DIVISION.
|
|
PROGRAM-ID. Main23SelectCond.
|
|
|
|
ENVIRONMENT DIVISION.
|
|
INPUT-OUTPUT SECTION.
|
|
FILE-CONTROL.
|
|
SELECT CUSTOMER-FILE ASSIGN TO "customer.dat"
|
|
ORGANIZATION IS INDEXED
|
|
ACCESS MODE IS DYNAMIC
|
|
RECORD KEY IS CUST-KEY
|
|
FILE STATUS IS CUST-STATUS.
|
|
SELECT REPORT-FILE ASSIGN TO "select-report.txt"
|
|
ORGANIZATION IS LINE SEQUENTIAL
|
|
FILE STATUS IS REPORT-STATUS.
|
|
SELECT TXN-LOG ASSIGN TO "txn-log.txt"
|
|
ORGANIZATION IS LINE SEQUENTIAL
|
|
FILE STATUS IS TXN-STATUS.
|
|
SELECT AUDIT-FILE ASSIGN TO "audit-file.txt"
|
|
ORGANIZATION IS LINE SEQUENTIAL
|
|
FILE STATUS IS AUDIT-STATUS.
|
|
|
|
DATA DIVISION.
|
|
FILE SECTION.
|
|
FD CUSTOMER-FILE.
|
|
01 CUST-RECORD.
|
|
05 CUST-KEY PIC X(10).
|
|
05 CUST-NAME PIC X(20).
|
|
05 CUST-BALANCE PIC 9(10).
|
|
FD REPORT-FILE.
|
|
01 REPORT-LINE PIC X(80).
|
|
FD TXN-LOG.
|
|
01 TXN-RECORD PIC X(120).
|
|
FD AUDIT-FILE.
|
|
01 AUDIT-RECORD PIC X(120).
|
|
|
|
WORKING-STORAGE SECTION.
|
|
01 WS-TELECOM-REC.
|
|
COPY "telecom/TEL-BILLING.cpy".
|
|
|
|
*> ---------- FILE STATUS flags ----------
|
|
01 CUST-STATUS PIC XX.
|
|
88 CUST-OK VALUE "00".
|
|
88 CUST-EOF VALUE "10".
|
|
88 CUST-NOTFOUND VALUE "23".
|
|
01 REPORT-STATUS PIC XX.
|
|
88 REPORT-OK VALUE "00".
|
|
01 TXN-STATUS PIC XX.
|
|
88 TXN-OK VALUE "00".
|
|
01 AUDIT-STATUS PIC XX.
|
|
88 AUDIT-OK VALUE "00".
|
|
|
|
*> ---------- Timestamp ----------
|
|
01 WS-DATE-SYS PIC 9(8).
|
|
01 WS-TIME-SYS PIC 9(8).
|
|
01 WS-TIMESTAMP-OUT PIC X(19).
|
|
01 WS-TS-DATE-FMT.
|
|
05 WS-TS-YEAR PIC X(4).
|
|
05 FILLER PIC X(1) VALUE "/".
|
|
05 WS-TS-MONTH PIC X(2).
|
|
05 FILLER PIC X(1) VALUE "/".
|
|
05 WS-TS-DAY PIC X(2).
|
|
01 WS-TS-TIME-FMT.
|
|
05 WS-TS-HOUR PIC X(2).
|
|
05 FILLER PIC X(1) VALUE ":".
|
|
05 WS-TS-MIN PIC X(2).
|
|
05 FILLER PIC X(1) VALUE ":".
|
|
05 WS-TS-SEC PIC X(2).
|
|
|
|
*> ---------- Error message ----------
|
|
01 WS-ERROR-MSG PIC X(60).
|
|
|
|
*> ---------- Existing query fields ----------
|
|
01 WS-CUST-COUNT PIC 9(02) VALUE 0.
|
|
01 WS-TEST-CASE PIC 9(02) VALUE 0.
|
|
01 WS-TOTAL-BALANCE PIC 9(10) VALUE 0.
|
|
01 WS-START-KEY PIC X(10).
|
|
01 WS-END-KEY PIC X(10).
|
|
01 WS-RANGE-LOW PIC X(10).
|
|
01 WS-RANGE-HIGH PIC X(10).
|
|
|
|
01 WS-HEADER1.
|
|
05 FILLER PIC X(20) VALUE "KEY NAME".
|
|
05 FILLER PIC X(20) VALUE " BALANCE".
|
|
01 WS-DETAIL-LINE.
|
|
05 DL-KEY PIC X(10).
|
|
05 FILLER PIC X(02) VALUE SPACES.
|
|
05 DL-NAME PIC X(20).
|
|
05 FILLER PIC X(02) VALUE SPACES.
|
|
05 DL-BALANCE PIC Z(9)9.
|
|
|
|
*> ---------- Test data ----------
|
|
01 CUST-DATA-AREA.
|
|
05 CUST-DATA OCCURS 6 TIMES.
|
|
10 CD-KEY PIC X(10).
|
|
10 CD-NAME PIC X(20).
|
|
10 CD-BALANCE PIC 9(10).
|
|
01 CUST-DATA-VALUES.
|
|
05 PIC X(40) VALUE "CUST000001ZHANG-SAN 0000001000".
|
|
05 PIC X(40) VALUE "CUST000002LI-SI 0000002000".
|
|
05 PIC X(40) VALUE "CUST000003WANG-WU 0000003000".
|
|
05 PIC X(40) VALUE "CUST000004ZHAO-QIAN 0000004000".
|
|
05 PIC X(40) VALUE "CUST000005SUN-LI 0000005000".
|
|
05 PIC X(40) VALUE "CUST000010ZHOU-WU 0000010000".
|
|
01 CUST-DATA-REDEF REDEFINES CUST-DATA-VALUES.
|
|
05 CUST-DATA-ENTRY OCCURS 6 TIMES.
|
|
10 CDE-KEY PIC X(10).
|
|
10 CDE-NAME PIC X(20).
|
|
10 CDE-BALANCE PIC 9(10).
|
|
01 IDX PIC 9(02).
|
|
|
|
*> ===== NEW FIELDS =====
|
|
*> Operation type statistics
|
|
01 WS-OP-BY-KEY-COUNT PIC 9(02) VALUE 0.
|
|
01 WS-OP-RANGE-COUNT PIC 9(02) VALUE 0.
|
|
01 WS-OP-GREATER-COUNT PIC 9(02) VALUE 0.
|
|
01 WS-FOUND-BY-KEY PIC 9(02) VALUE 0.
|
|
01 WS-FOUND-RANGE PIC 9(02) VALUE 0.
|
|
01 WS-FOUND-GREATER PIC 9(02) VALUE 0.
|
|
*> Search performance metrics
|
|
01 WS-PERF-READS PIC 9(02) VALUE 0.
|
|
01 WS-PERF-START-READS PIC 9(02) VALUE 0.
|
|
01 WS-PERF-RANGE-READS PIC 9(02) VALUE 0.
|
|
01 WS-PERF-GREATER-READS PIC 9(02) VALUE 0.
|
|
*> Hash total for data integrity
|
|
01 WS-HASH-TOTAL PIC 9(12) VALUE 0.
|
|
*> Batch control totals
|
|
01 WS-BC-TOTAL-REQUESTS PIC 9(02) VALUE 0.
|
|
01 WS-BC-TOTAL-FOUND PIC 9(02) VALUE 0.
|
|
01 WS-BC-TOTAL-NOTFOUND PIC 9(02) VALUE 0.
|
|
*> Key validation flag
|
|
01 WS-KEY-VALID-FLAG PIC X(01).
|
|
88 WS-KEY-VALID-YES VALUE "Y".
|
|
88 WS-KEY-VALID-NO VALUE "N".
|
|
*> Transaction log work area
|
|
01 WS-TXN-BUFFER PIC X(120).
|
|
01 WS-TXN-TYPE PIC X(15).
|
|
01 WS-TXN-DETAIL PIC X(88).
|
|
|
|
PROCEDURE DIVISION.
|
|
MAIN-PROCEDURE.
|
|
PERFORM 1000-INIT THRU 1000-EXIT
|
|
PERFORM 2000-OPEN-FILES THRU 2000-EXIT
|
|
PERFORM 3000-READ-INPUT THRU 3000-EXIT
|
|
PERFORM 4000-REPORT THRU 4000-EXIT
|
|
PERFORM 5000-AUDIT THRU 5000-EXIT
|
|
PERFORM 9000-EXIT-PGM THRU 9000-EXIT
|
|
STOP RUN.
|
|
|
|
*> ============================================================
|
|
*> 1000-INIT : Create INDEXED file, populate with test data
|
|
*> ============================================================
|
|
1000-INIT SECTION.
|
|
1000-START.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 1000-INIT: Starting".
|
|
|
|
OPEN OUTPUT CUSTOMER-FILE.
|
|
IF NOT CUST-OK
|
|
MOVE "1000: OPEN OUTPUT CUST FAILED" TO WS-ERROR-MSG
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
CLOSE CUSTOMER-FILE.
|
|
IF NOT CUST-OK
|
|
MOVE "1000: CLOSE CUST (post-OUTPUT) FAILED"
|
|
TO WS-ERROR-MSG
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
OPEN I-O CUSTOMER-FILE.
|
|
IF NOT CUST-OK
|
|
MOVE "1000: OPEN I-O CUST FAILED" TO WS-ERROR-MSG
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
|
|
PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 6
|
|
MOVE CDE-KEY(IDX) TO CUST-KEY
|
|
MOVE CDE-NAME(IDX) TO CUST-NAME
|
|
MOVE CDE-BALANCE(IDX) TO CUST-BALANCE
|
|
WRITE CUST-RECORD
|
|
INVALID KEY
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "]"
|
|
" INIT INSERT FAILED: " CUST-STATUS
|
|
END-WRITE
|
|
IF NOT CUST-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] INIT WRITE FAILED"
|
|
" KEY=" CUST-KEY " STATUS=" CUST-STATUS
|
|
END-IF
|
|
END-PERFORM.
|
|
|
|
CLOSE CUSTOMER-FILE.
|
|
IF NOT CUST-OK
|
|
MOVE "1000: CLOSE CUST (post-WRITE) FAILED"
|
|
TO WS-ERROR-MSG
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
OPEN I-O CUSTOMER-FILE.
|
|
IF NOT CUST-OK
|
|
MOVE "1000: OPEN I-O (reopen) FAILED" TO WS-ERROR-MSG
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 1000-INIT: Complete".
|
|
GO TO 1000-EXIT.
|
|
1000-EXIT.
|
|
EXIT.
|
|
|
|
*> ============================================================
|
|
*> 2000-OPEN-FILES : Open output files, write audit header
|
|
*> ============================================================
|
|
2000-OPEN-FILES SECTION.
|
|
2000-START.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 2000-OPEN-FILES:"
|
|
" Opening output files".
|
|
|
|
OPEN OUTPUT REPORT-FILE.
|
|
IF NOT REPORT-OK
|
|
MOVE "2000: OPEN REPORT FAILED" TO WS-ERROR-MSG
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
OPEN OUTPUT TXN-LOG.
|
|
IF NOT TXN-OK
|
|
MOVE "2000: OPEN TXN-LOG FAILED" TO WS-ERROR-MSG
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
OPEN OUTPUT AUDIT-FILE.
|
|
IF NOT AUDIT-OK
|
|
MOVE "2000: OPEN AUDIT FAILED" TO WS-ERROR-MSG
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
|
|
PERFORM GET-TIMESTAMP.
|
|
WRITE AUDIT-RECORD FROM SPACES.
|
|
STRING "*** AUDIT START *** " WS-TIMESTAMP-OUT
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
IF NOT AUDIT-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] AUDIT HEADER WRITE"
|
|
" FAILED STATUS=" AUDIT-STATUS
|
|
END-IF.
|
|
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 2000: All files opened".
|
|
GO TO 2000-EXIT.
|
|
2000-EXIT.
|
|
EXIT.
|
|
|
|
*> ============================================================
|
|
*> 3000-READ-INPUT : Execute 4 test cases (by-key, range,
|
|
*> zero-results, greater-than). Each includes key validation,
|
|
*> search execution, statistics update, and TXN log entry.
|
|
*> ============================================================
|
|
3000-READ-INPUT SECTION.
|
|
3000-START.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 3000-READ-INPUT:"
|
|
" Starting test cases".
|
|
|
|
*> Report header
|
|
MOVE WS-HEADER1 TO REPORT-LINE.
|
|
WRITE REPORT-LINE.
|
|
IF NOT REPORT-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] REPORT HEADER WRITE"
|
|
" FAILED STATUS=" REPORT-STATUS
|
|
END-IF.
|
|
|
|
*> === TEST 1 : WHERE key = 'CUST000003' ===
|
|
ADD 1 TO WS-TEST-CASE.
|
|
ADD 1 TO WS-BC-TOTAL-REQUESTS.
|
|
MOVE 0 TO WS-PERF-READS.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] === Test " WS-TEST-CASE
|
|
": WHERE key = 'CUST000003' ===".
|
|
MOVE "CUST000003" TO WS-START-KEY.
|
|
MOVE WS-START-KEY TO CUST-KEY.
|
|
PERFORM 3100-VALIDATE-KEY THRU 3100-EXIT.
|
|
PERFORM 3200-SELECT-BY-KEY.
|
|
ADD WS-CUST-COUNT TO WS-BC-TOTAL-FOUND.
|
|
ADD 1 TO WS-OP-BY-KEY-COUNT.
|
|
ADD WS-PERF-READS TO WS-PERF-START-READS.
|
|
MOVE "BY-KEY" TO WS-TXN-TYPE.
|
|
STRING "KEY=" WS-START-KEY " FOUND=" WS-CUST-COUNT
|
|
INTO WS-TXN-DETAIL
|
|
END-STRING.
|
|
PERFORM 5000-TXN-LOG.
|
|
|
|
*> === TEST 2 : key >= 'CUST000002' AND <= 'CUST000005' ===
|
|
ADD 1 TO WS-TEST-CASE.
|
|
ADD 1 TO WS-BC-TOTAL-REQUESTS.
|
|
MOVE 0 TO WS-PERF-READS.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] === Test " WS-TEST-CASE
|
|
": WHERE key >= 'CUST000002'"
|
|
" AND key <= 'CUST000005' ===".
|
|
MOVE "CUST000002" TO WS-RANGE-LOW.
|
|
MOVE "CUST000005" TO WS-RANGE-HIGH.
|
|
MOVE WS-RANGE-LOW TO CUST-KEY.
|
|
PERFORM 3100-VALIDATE-KEY THRU 3100-EXIT.
|
|
MOVE WS-RANGE-HIGH TO CUST-KEY.
|
|
PERFORM 3100-VALIDATE-KEY THRU 3100-EXIT.
|
|
PERFORM 3200-SELECT-RANGE.
|
|
ADD WS-CUST-COUNT TO WS-BC-TOTAL-FOUND.
|
|
ADD 1 TO WS-OP-RANGE-COUNT.
|
|
ADD WS-PERF-READS TO WS-PERF-RANGE-READS.
|
|
MOVE "RANGE" TO WS-TXN-TYPE.
|
|
STRING "LOW=" WS-RANGE-LOW " HIGH=" WS-RANGE-HIGH
|
|
" FOUND=" WS-CUST-COUNT
|
|
INTO WS-TXN-DETAIL
|
|
END-STRING.
|
|
PERFORM 5000-TXN-LOG.
|
|
|
|
*> === TEST 3 : WHERE none match (key = 'ZZZZZZZZZZ') ===
|
|
ADD 1 TO WS-TEST-CASE.
|
|
ADD 1 TO WS-BC-TOTAL-REQUESTS.
|
|
MOVE 0 TO WS-PERF-READS.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] === Test " WS-TEST-CASE
|
|
": WHERE none match ===".
|
|
MOVE "ZZZZZZZZZZ" TO WS-START-KEY.
|
|
MOVE WS-START-KEY TO CUST-KEY.
|
|
PERFORM 3100-VALIDATE-KEY THRU 3100-EXIT.
|
|
PERFORM 3200-SELECT-BY-KEY.
|
|
ADD WS-CUST-COUNT TO WS-BC-TOTAL-FOUND.
|
|
IF WS-CUST-COUNT = 0
|
|
ADD 1 TO WS-BC-TOTAL-NOTFOUND
|
|
END-IF.
|
|
ADD WS-PERF-READS TO WS-PERF-START-READS.
|
|
MOVE "BY-KEY" TO WS-TXN-TYPE.
|
|
STRING "KEY=" WS-START-KEY " FOUND=" WS-CUST-COUNT
|
|
INTO WS-TXN-DETAIL
|
|
END-STRING.
|
|
PERFORM 5000-TXN-LOG.
|
|
|
|
*> === TEST 4 : WHERE key > 'CUST000003' ===
|
|
ADD 1 TO WS-TEST-CASE.
|
|
ADD 1 TO WS-BC-TOTAL-REQUESTS.
|
|
MOVE 0 TO WS-PERF-READS.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] === Test " WS-TEST-CASE
|
|
": WHERE key > 'CUST000003' ===".
|
|
MOVE "CUST000003" TO WS-START-KEY.
|
|
MOVE WS-START-KEY TO CUST-KEY.
|
|
PERFORM 3100-VALIDATE-KEY THRU 3100-EXIT.
|
|
PERFORM 3200-SELECT-GREATER-THAN.
|
|
ADD WS-CUST-COUNT TO WS-BC-TOTAL-FOUND.
|
|
ADD 1 TO WS-OP-GREATER-COUNT.
|
|
ADD WS-PERF-READS TO WS-PERF-GREATER-READS.
|
|
MOVE "GREATER-THAN" TO WS-TXN-TYPE.
|
|
STRING "KEY>" WS-START-KEY " FOUND=" WS-CUST-COUNT
|
|
INTO WS-TXN-DETAIL
|
|
END-STRING.
|
|
PERFORM 5000-TXN-LOG.
|
|
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 3000: All test cases done".
|
|
GO TO 3000-EXIT.
|
|
3000-EXIT.
|
|
EXIT.
|
|
|
|
*> ============================================================
|
|
*> 3100-VALIDATE-KEY : Validate key format "CUST" + 6 digits.
|
|
*> Sets WS-KEY-VALID-FLAG to "Y"/"N".
|
|
*> ============================================================
|
|
3100-VALIDATE-KEY SECTION.
|
|
3100-START.
|
|
MOVE "Y" TO WS-KEY-VALID-FLAG.
|
|
IF CUST-KEY(1:4) NOT = "CUST"
|
|
MOVE "N" TO WS-KEY-VALID-FLAG
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] VALIDATE: key ["
|
|
CUST-KEY "] prefix not 'CUST'"
|
|
END-IF.
|
|
*> Check that positions 5-10 are all numeric digits
|
|
PERFORM VARYING IDX FROM 5 BY 1 UNTIL IDX > 10
|
|
IF CUST-KEY(IDX:1) < "0" OR CUST-KEY(IDX:1) > "9"
|
|
MOVE "N" TO WS-KEY-VALID-FLAG
|
|
END-IF
|
|
END-PERFORM.
|
|
IF WS-KEY-VALID-NO
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] VALIDATE: key ["
|
|
CUST-KEY "] INVALID FORMAT"
|
|
END-IF.
|
|
GO TO 3100-EXIT.
|
|
3100-EXIT.
|
|
EXIT.
|
|
|
|
*> ============================================================
|
|
*> 3200-PROCESS-RECORD : Populate detail line, accumulate hash
|
|
*> total, display result, and write to report.
|
|
*> ============================================================
|
|
3200-PROCESS-RECORD SECTION.
|
|
3200-START.
|
|
MOVE CUST-KEY TO DL-KEY.
|
|
MOVE CUST-NAME TO DL-NAME.
|
|
MOVE CUST-BALANCE TO DL-BALANCE.
|
|
ADD CUST-BALANCE TO WS-HASH-TOTAL.
|
|
DISPLAY " " WS-DETAIL-LINE.
|
|
PERFORM 3300-WRITE-OUTPUT THRU 3300-EXIT.
|
|
GO TO 3200-EXIT.
|
|
3200-EXIT.
|
|
EXIT.
|
|
|
|
*> ---- Single-record read by primary key ----
|
|
3200-SELECT-BY-KEY.
|
|
MOVE 0 TO WS-CUST-COUNT.
|
|
MOVE WS-START-KEY TO CUST-KEY.
|
|
READ CUSTOMER-FILE KEY IS CUST-KEY
|
|
INVALID KEY
|
|
PERFORM GET-TIMESTAMP
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] KEY NOT FOUND: "
|
|
WS-START-KEY
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] ROW EXISTENCE"
|
|
" CHECK: no record for key "
|
|
WS-START-KEY " STATUS=" CUST-STATUS
|
|
MOVE " KEY NOT FOUND" TO REPORT-LINE
|
|
WRITE REPORT-LINE
|
|
IF NOT REPORT-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] REPORT WRITE"
|
|
" FAILED STATUS=" REPORT-STATUS
|
|
END-IF
|
|
NOT INVALID KEY
|
|
ADD 1 TO WS-CUST-COUNT
|
|
PERFORM 3200-PROCESS-RECORD THRU 3200-EXIT
|
|
END-READ.
|
|
IF NOT CUST-OK AND NOT CUST-NOTFOUND
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] READ FAILED"
|
|
" STATUS=" CUST-STATUS
|
|
END-IF.
|
|
ADD 1 TO WS-PERF-READS.
|
|
|
|
*> ---- Range search via START / READ NEXT ----
|
|
3200-SELECT-RANGE.
|
|
MOVE 0 TO WS-CUST-COUNT.
|
|
MOVE WS-RANGE-LOW TO CUST-KEY.
|
|
START CUSTOMER-FILE KEY IS NOT LESS THAN CUST-KEY
|
|
IF CUST-STATUS NOT = "00"
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] RANGE START"
|
|
" FAILED STATUS=" CUST-STATUS
|
|
MOVE " RANGE START FAILED" TO REPORT-LINE
|
|
WRITE REPORT-LINE
|
|
ELSE
|
|
PERFORM UNTIL CUST-EOF
|
|
READ CUSTOMER-FILE NEXT RECORD
|
|
AT END
|
|
SET CUST-EOF TO TRUE
|
|
NOT AT END
|
|
IF CUST-KEY > WS-RANGE-HIGH
|
|
SET CUST-EOF TO TRUE
|
|
ELSE
|
|
ADD 1 TO WS-CUST-COUNT
|
|
PERFORM 3200-PROCESS-RECORD
|
|
THRU 3200-EXIT
|
|
END-IF
|
|
END-READ
|
|
IF CUST-OK
|
|
ADD 1 TO WS-PERF-READS
|
|
END-IF
|
|
END-PERFORM
|
|
END-IF.
|
|
|
|
*> ---- Greater-than search via START / READ NEXT ----
|
|
3200-SELECT-GREATER-THAN.
|
|
MOVE 0 TO WS-CUST-COUNT.
|
|
MOVE WS-START-KEY TO CUST-KEY.
|
|
START CUSTOMER-FILE KEY IS GREATER THAN CUST-KEY
|
|
IF CUST-STATUS NOT = "00"
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] GREATER START"
|
|
" FAILED STATUS=" CUST-STATUS
|
|
ELSE
|
|
PERFORM UNTIL CUST-EOF
|
|
READ CUSTOMER-FILE NEXT RECORD
|
|
AT END
|
|
SET CUST-EOF TO TRUE
|
|
NOT AT END
|
|
ADD 1 TO WS-CUST-COUNT
|
|
PERFORM 3200-PROCESS-RECORD
|
|
THRU 3200-EXIT
|
|
END-READ
|
|
IF CUST-OK
|
|
ADD 1 TO WS-PERF-READS
|
|
END-IF
|
|
END-PERFORM
|
|
END-IF.
|
|
|
|
*> ============================================================
|
|
*> 3300-WRITE-OUTPUT : Write a single detail line to report
|
|
*> ============================================================
|
|
3300-WRITE-OUTPUT SECTION.
|
|
3300-START.
|
|
MOVE WS-DETAIL-LINE TO REPORT-LINE.
|
|
WRITE REPORT-LINE.
|
|
IF NOT REPORT-OK
|
|
MOVE "3300: WRITE REPORT FAILED" TO WS-ERROR-MSG
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] " WS-ERROR-MSG
|
|
" STATUS=" REPORT-STATUS
|
|
PERFORM 6000-ERROR-HANDLE THRU 6000-EXIT
|
|
END-IF.
|
|
GO TO 3300-EXIT.
|
|
3300-EXIT.
|
|
EXIT.
|
|
|
|
*> ============================================================
|
|
*> 4000-REPORT : Summary with batch totals, operation stats,
|
|
*> hash totals, and performance metrics
|
|
*> ============================================================
|
|
4000-REPORT SECTION.
|
|
4000-START.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 4000-REPORT:"
|
|
" Generating summary".
|
|
|
|
WRITE REPORT-LINE FROM SPACES.
|
|
MOVE "=== BATCH CONTROL TOTALS ===" TO REPORT-LINE.
|
|
WRITE REPORT-LINE.
|
|
STRING "Total search requests : " WS-BC-TOTAL-REQUESTS
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
STRING "Total records found : " WS-BC-TOTAL-FOUND
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
STRING "Total records not found: " WS-BC-TOTAL-NOTFOUND
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
|
|
WRITE REPORT-LINE FROM SPACES.
|
|
MOVE "=== OPERATION TYPE STATISTICS ===" TO REPORT-LINE.
|
|
WRITE REPORT-LINE.
|
|
STRING "By-key searches : " WS-OP-BY-KEY-COUNT
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
STRING "Range searches : " WS-OP-RANGE-COUNT
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
STRING "Greater searches : " WS-OP-GREATER-COUNT
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
|
|
WRITE REPORT-LINE FROM SPACES.
|
|
MOVE "=== DATA INTEGRITY HASH TOTALS ===" TO REPORT-LINE.
|
|
WRITE REPORT-LINE.
|
|
STRING "Hash total (CUST-BALANCE sum): " WS-HASH-TOTAL
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
|
|
WRITE REPORT-LINE FROM SPACES.
|
|
MOVE "=== SEARCH PERFORMANCE METRICS ===" TO REPORT-LINE.
|
|
WRITE REPORT-LINE.
|
|
STRING "Total READs (by-key) : " WS-PERF-START-READS
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
STRING "Total READs (range) : " WS-PERF-RANGE-READS
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
STRING "Total READs (greater-than): " WS-PERF-GREATER-READS
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 4000: Report written".
|
|
GO TO 4000-EXIT.
|
|
4000-EXIT.
|
|
EXIT.
|
|
|
|
*> ============================================================
|
|
*> 5000-AUDIT : Write operation summary to audit file with
|
|
*> timestamps, statistics, hash totals, and performance data
|
|
*> ============================================================
|
|
5000-AUDIT SECTION.
|
|
5000-START.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 5000-AUDIT:"
|
|
" Writing audit records".
|
|
|
|
WRITE AUDIT-RECORD FROM SPACES.
|
|
MOVE "--- OPERATION SUMMARY ---" TO AUDIT-RECORD.
|
|
WRITE AUDIT-RECORD.
|
|
STRING " Program: Main23SelectCond Timestamp: "
|
|
WS-TIMESTAMP-OUT
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
STRING " Test cases: " WS-TEST-CASE
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
|
|
WRITE AUDIT-RECORD FROM SPACES.
|
|
MOVE " Search type breakdown:" TO AUDIT-RECORD.
|
|
WRITE AUDIT-RECORD.
|
|
STRING " By-key : " WS-OP-BY-KEY-COUNT
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
STRING " Range : " WS-OP-RANGE-COUNT
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
STRING " Greater-than: " WS-OP-GREATER-COUNT
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
|
|
WRITE AUDIT-RECORD FROM SPACES.
|
|
MOVE " Batch control totals:" TO AUDIT-RECORD.
|
|
WRITE AUDIT-RECORD.
|
|
STRING " Requests: " WS-BC-TOTAL-REQUESTS
|
|
" Found: " WS-BC-TOTAL-FOUND
|
|
" NotFound: " WS-BC-TOTAL-NOTFOUND
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
|
|
WRITE AUDIT-RECORD FROM SPACES.
|
|
MOVE " Data integrity:" TO AUDIT-RECORD.
|
|
WRITE AUDIT-RECORD.
|
|
STRING " Hash total (balance): " WS-HASH-TOTAL
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
|
|
WRITE AUDIT-RECORD FROM SPACES.
|
|
MOVE " Performance metrics:" TO AUDIT-RECORD.
|
|
WRITE AUDIT-RECORD.
|
|
STRING " ByKey=" WS-PERF-START-READS
|
|
" Range=" WS-PERF-RANGE-READS
|
|
" Greater=" WS-PERF-GREATER-READS
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
|
|
WRITE AUDIT-RECORD FROM SPACES.
|
|
PERFORM GET-TIMESTAMP.
|
|
STRING "*** AUDIT END *** " WS-TIMESTAMP-OUT
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
IF NOT AUDIT-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] AUDIT END WRITE"
|
|
" FAILED STATUS=" AUDIT-STATUS
|
|
END-IF.
|
|
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 5000: Audit written".
|
|
GO TO 5000-EXIT.
|
|
5000-EXIT.
|
|
EXIT.
|
|
|
|
*> ---- Transaction log entry ----
|
|
5000-TXN-LOG.
|
|
PERFORM GET-TIMESTAMP.
|
|
STRING WS-TXN-TYPE " | " WS-TXN-DETAIL
|
|
" | " WS-TIMESTAMP-OUT
|
|
INTO WS-TXN-BUFFER
|
|
END-STRING.
|
|
MOVE WS-TXN-BUFFER TO TXN-RECORD.
|
|
WRITE TXN-RECORD.
|
|
IF NOT TXN-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] TXN LOG WRITE"
|
|
" FAILED STATUS=" TXN-STATUS
|
|
END-IF.
|
|
|
|
*> ============================================================
|
|
*> 6000-ERROR-HANDLE : Log errors to DISPLAY, audit, report,
|
|
*> and transaction log
|
|
*> ============================================================
|
|
6000-ERROR-HANDLE SECTION.
|
|
6000-START.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 6000-ERROR: " WS-ERROR-MSG.
|
|
STRING "ERROR: " WS-ERROR-MSG " at " WS-TIMESTAMP-OUT
|
|
INTO AUDIT-RECORD
|
|
END-STRING.
|
|
WRITE AUDIT-RECORD.
|
|
STRING "ERROR: " WS-ERROR-MSG " at " WS-TIMESTAMP-OUT
|
|
INTO REPORT-LINE
|
|
END-STRING.
|
|
WRITE REPORT-LINE.
|
|
MOVE "ERROR" TO WS-TXN-TYPE.
|
|
MOVE WS-ERROR-MSG TO WS-TXN-DETAIL.
|
|
PERFORM 5000-TXN-LOG.
|
|
GO TO 6000-EXIT.
|
|
6000-EXIT.
|
|
EXIT.
|
|
|
|
*> ============================================================
|
|
*> 9000-EXIT-PGM : Close all files, display final summary
|
|
*> ============================================================
|
|
9000-EXIT-PGM SECTION.
|
|
9000-START.
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] 9000-EXIT: Closing files".
|
|
|
|
CLOSE REPORT-FILE.
|
|
IF NOT REPORT-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] CLOSE REPORT-FILE"
|
|
" FAILED STATUS=" REPORT-STATUS
|
|
END-IF.
|
|
CLOSE CUSTOMER-FILE.
|
|
IF NOT CUST-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] CLOSE CUSTOMER-FILE"
|
|
" FAILED STATUS=" CUST-STATUS
|
|
END-IF.
|
|
CLOSE TXN-LOG.
|
|
IF NOT TXN-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] CLOSE TXN-LOG"
|
|
" FAILED STATUS=" TXN-STATUS
|
|
END-IF.
|
|
CLOSE AUDIT-FILE.
|
|
IF NOT AUDIT-OK
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] CLOSE AUDIT-FILE"
|
|
" FAILED STATUS=" AUDIT-STATUS
|
|
END-IF.
|
|
|
|
PERFORM GET-TIMESTAMP.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] ====== Finished =====".
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] Requests:"
|
|
WS-BC-TOTAL-REQUESTS " Found:" WS-BC-TOTAL-FOUND
|
|
" NotFound:" WS-BC-TOTAL-NOTFOUND.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] Hash total:" WS-HASH-TOTAL.
|
|
DISPLAY "[" WS-TIMESTAMP-OUT "] Reads ByKey:"
|
|
WS-PERF-START-READS " Range:" WS-PERF-RANGE-READS
|
|
" Greater:" WS-PERF-GREATER-READS.
|
|
GO TO 9000-EXIT.
|
|
9000-EXIT.
|
|
EXIT.
|
|
|
|
*> ============================================================
|
|
*> GET-TIMESTAMP : Build WS-TIMESTAMP-OUT = YYYY/MM/DD HH:MM:SS
|
|
*> ============================================================
|
|
GET-TIMESTAMP.
|
|
ACCEPT WS-DATE-SYS FROM DATE YYYYMMDD.
|
|
ACCEPT WS-TIME-SYS FROM TIME.
|
|
MOVE WS-DATE-SYS(1:4) TO WS-TS-YEAR.
|
|
MOVE WS-DATE-SYS(5:2) TO WS-TS-MONTH.
|
|
MOVE WS-DATE-SYS(7:2) TO WS-TS-DAY.
|
|
MOVE WS-TIME-SYS(1:2) TO WS-TS-HOUR.
|
|
MOVE WS-TIME-SYS(3:2) TO WS-TS-MIN.
|
|
MOVE WS-TIME-SYS(5:2) TO WS-TS-SEC.
|
|
STRING WS-TS-DATE-FMT " " WS-TS-TIME-FMT
|
|
INTO WS-TIMESTAMP-OUT
|
|
END-STRING.
|