PROGRAM RUFEXAMPLE (OUTPUT); { This program demonstrates the calls necessary for recovery unit journaling. It is meant as an example of use in PASCAL, it does not implement complete error checking. } (* Declare system services used in program *) FUNCTION SYS$START_RU (VAR Recovery_unit_handle : [LONG] INTEGER): INTEGER; EXTERN; PROCEDURE SYS$ABORT_RU (VAR Recovery_unit_handle : [LONG] INTEGER); EXTERN; FUNCTION SYS$END_RU (VAR Recovery_unit_handle : [LONG] INTEGER): INTEGER; EXTERN; PROCEDURE LIB$WAIT (delay: integer); EXTERN; PROCEDURE LIB$SIGNAL (%IMMED Cond_Value: integer); EXTERN; TYPE STRING9 = PACKED ARRAY [1..9]OF CHAR; (* For primary key string *) { Structure used for the checking and savings account files. } Account_record = RECORD Number: [KEY(0)] STRING9; (* Account number - Primary key *) Balance: INTEGER; (* Account balance *) filler: PACKED ARRAY [1..5]OF CHAR; (* Filler for compatibility *) END; VAR Recovery_unit_handle: [LONG] INTEGER; Checking_account_file : FILE OF Account_record; Savings_account_file : FILE OF Account_record; Checking_account: Account_record; Savings_account: Account_record; Sys_stat: integer; BEGIN { Open the checking and savings account files. } OPEN (Checking_account_file, 'RUF$CHECKING.DAT', HISTORY := OLD, ACCESS_METHOD := KEYED, ORGANIZATION := INDEXED); OPEN (savings_account_file, 'RUF$SAVINGS.DAT', HISTORY := OLD, ACCESS_METHOD := KEYED, ORGANIZATION := INDEXED); { Recovery unit to initialize savings and checking account files. Note that any I/O errors in this recovery unit will be ignored. The checking and savings account will be initialized to $100 for account "000001234". } Sys_stat := SYS$START_RU (Recovery_unit_handle); IF NOT ODD (Sys_stat) THEN BEGIN WRITELN ('Cannot start recovery unit.'); LIB$SIGNAL(Sys_stat); END; { Put $100 dollars in the checking account of "000001234" } Checking_account.number := '000001234'; Checking_account.balance:= 100; WRITE (Checking_account_file, Checking_account, ERROR := CONTINUE); IF STATUS (Checking_account_file) <> 0 THEN WRITELN ('Checking account already exists'); { Put $100 dollars in the savings account of "000001234" } Savings_account.number := '000001234'; Savings_account.balance:= 100; WRITE (Savings_account_file, Savings_account, ERROR := CONTINUE); IF STATUS (Savings_account_file) <> 0 THEN WRITELN ('Savings account already exists'); { End the recovery unit to initialize the checking and savings account } Sys_stat := SYS$END_RU (Recovery_unit_handle); IF NOT ODD (Sys_stat) THEN BEGIN WRITELN (' Cannot end recovery unit to initialize accounts'); LIB$SIGNAL(Sys_stat); END; { Transfer $10.00 from checking to savings using a recovery unit. Note that the recovery unit is aborted if any I/O errors are encountered. } Sys_stat := SYS$START_RU (Recovery_unit_handle); IF NOT ODD (Sys_stat) THEN BEGIN WRITELN (' Cannot start recovery unit to transfer funds'); LIB$SIGNAL (Sys_stat); END; { Read the checking account record for "000001234". Abort recovery unit if the operation is not successful. } Checking_account.number := '000001234'; FINDK (Checking_account_file, 0, Checking_account.number, EQL, ERROR := CONTINUE); IF UFB (Checking_account_file) THEN BEGIN WRITELN ('Cannot read checking account balance'); SYS$ABORT_RU (Recovery_unit_handle); END; READ (Checking_account_file, Checking_account); { Subtract $10 from the checking account balance. } Checking_account.balance := Checking_account.balance - 10; { Update the checking account file reflecting the new balance. Abort the recovery unit if the update is not successful. } FINDK (Checking_account_file, 0, Checking_account.number, EQL, ERROR := CONTINUE); Checking_account_file^ := Checking_account; UPDATE (Checking_account_file, ERROR := CONTINUE); IF (STATUS (Checking_account_file) <> 0) THEN BEGIN WRITELN ('Cannot update checking account balance'); SYS$ABORT_RU (Recovery_unit_handle); END; WRITELN ('Pausing for 5 seconds....'); LIB$WAIT (5); { Read the savings account record for "000001234". Abort recovery unit if the operation is not successful. } Savings_account.number := '000001234'; FINDK (Savings_account_file, 0, Savings_account.number, EQL, ERROR := CONTINUE); IF UFB (Savings_account_file) THEN BEGIN WRITELN ('Cannot read Savings account balance'); SYS$ABORT_RU (Recovery_unit_handle); END; READ (Savings_account_file, Savings_account); { Add $10 to the savings account. } Savings_account.balance := Savings_account.balance + 10; { Update the savings account file reflecting the new balance. Abort the recovery unit if the update is not successful. } FINDK (Savings_account_file, 0, Savings_account.number, EQL, ERROR := CONTINUE); Savings_account_file^ := Savings_account; UPDATE (Savings_account_file, ERROR := CONTINUE); IF (STATUS (Savings_account_file) <> 0) THEN BEGIN WRITELN ('Cannot update Savings account balance'); SYS$ABORT_RU (Recovery_unit_handle); END; { End the recovery unit. } Sys_stat := SYS$END_RU (Recovery_unit_handle); IF NOT ODD (Sys_stat) THEN BEGIN WRITELN (' Cannot end recovery unit to transfer'); LIB$SIGNAL (Sys_stat); END; { Display the new balances. } WRITELN ('The new checking account balance is $',checking_account.balance:3); WRITELN ('The new savings account balance is $',savings_account.balance:3); { Close the checking and savings account files. } CLOSE (Checking_account_file, disposition := save); CLOSE (Savings_account_file, disposition := save); END.