Oracle Enterprise Manager Oracle Trace User's Guide | ![]() Library |
![]() Product |
![]() Contents |
![]() Index |
This appendix provides a sample instrumented application.
Running the ATM Sample Application
To install and run the ATM sample application provided by Oracle Trace, take the following steps:
setenv ORACLE_HOME /oracle/product
setenv ORACLE_SID trace
Number of Records
|
Number of Data Blocks (2048 Bytes Each)
|
---|---|
100
|
10
|
2,500
|
100
|
10,000
|
400
|
% sqlplus system\manager
SQL> create user atm identified by sampleatm
2> default tablespace is <atm_space> quota
3> unlimitd on <atm_space>;
SQL> grant create session, create table to atm;
SQL> disconnect
SQL> connect atm\sampleatm
SQL> @atmtab
SQL> @atmdat
SQL> @atmind
% cp $ORACLE_HOME/otrace/demo/atm.fdf $ORACLE_HOME/rdbms/demo
% atmoci atm.inp
input file is atm.inp
/* Copyright (c) Oracle Corporation 1995. All Rights Reserved. */
/*
NAME
atmpc.pc -- Trace ATM sample application using PRO*C interface
DESCRIPTION
Simulates an ATM, allowing balance inquiries, deposits and withdrawals
*/
#include <stdio.h>
#include <stdlib.h>
#include <epc.h>
#define S_LONG 4 /* use instead of sizeof(long) */
#define TRUE 1
#define FALSE 0
#define MAXLINE 80 /* maximum length of input line */
#define API_VERSION 1
#define VENDOR 192216243
#define FACILITY_NUMBER 1
#define MAX_EVENT 9 /* number of events */
#define BALANCES 1 /* event numbers */
#define DEPOSIT 2
#define WITHDRAWAL 3
#define TRANSFER 4
#define QUICK_WITHDRAW 5
#define OVERDRAFT 6
#define USER_SESSION 7
#define VALIDATION_OK 8
#define VALIDATION_ERR 9
/* macros to simplify input/output */
#define DISPLAY(text) if (!FromFile) printf(text)
#define READ(text) if (FromFile) fgets(text, MAXLINE, InFile); else gets(text)
/* Function declarations */
void INIT_ATM(/* int argc, char *argv[] */);
void END_ATM(/* void */);
long LOGIN_USER(/* void */);
void INIT_USER_SESSION(/* void */);
void END_USER_SESSION(/* void */);
long DISPLAY_MAIN_MENU(/* void */);
void GET_BALANCES(/* long acct_num */);
void MAKE_DEPOSIT(/* long acct_num */);
void MAKE_WITHDRAWAL(/* long acct_num */);
void MAKE_TRANSFER(/* long acct_num */);
long MAKE_QUICK_WITHDRAWAL(/* long acct_num */);
long ATM_VALID_ACCT_NUM(/* long acct_num */);
long ATM_VALID_XFER_ACCT(/* long acct_num */);
float ATM_SAV_BALANCE(/* long acct_num */);
float ATM_CHK_BALANCE(/* long acct_num */);
void ATM_SAV_DEPOSIT(/* long acct_num, long amount */);
void ATM_CHK_DEPOSIT(/* long acct_num, long amount */);
void ATM_SAV_WITHDRAWAL(/* long acct_num, long amount */);
void ATM_CHK_WITHDRAWAL(/* long acct_num, long amount */);
void ATM_START_RW(/* void */);
void ATM_START_RO(/* void */);
void ATM_COMMIT(/* void */);
void ATM_ROLLBACK(/* void */);
EXEC SQL INCLUDE sqlca;
long SQLCODE; /* SQL return status code */
EXEC SQL BEGIN DECLARE SECTION; /* declare SQL host variables */
long acct_num; /* passed as parameters in most */
long amount; /* SQL routines */
EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER NOT FOUND CONTINUE; /* keep running if record not found */
FILE *InFile; /* input file */
char FromFile; /* true if reading from input file */
char Version[10]; /* Product version string */
char Collection_Name[80]; /* Name of collection file */
char FDF_Name[80]; /* Name of facility definition file */
char Regist_ID[80]; /* reusable registration ID text */
long *Event_Flags; /* Trace event flags set by epc_init */
long Session_Handle; /* event instance handles */
long Txn_Handle;
main (argc, argv)
int argc;
char *argv[];
{
char user = TRUE; /* we're accepting users */
char session; /* we have a valid user */
long acct_num; /* user's account number */
long choice; /* user's menu choice */
char exit_early; /* user finished without picking */
/* exit from menu */
INIT_ATM (argc, argv);
while (user)
{
acct_num = LOGIN_USER(); /* returns valid acct_num or 0 */
if (acct_num == 0)
{
session = FALSE;
user = FALSE;
}
else
{
session = TRUE;
INIT_USER_SESSION(); /* start user_session event */
}
while (session)
{
choice = DISPLAY_MAIN_MENU();
switch (choice)
{
case 1:
GET_BALANCES(acct_num);
break;
case 2:
MAKE_DEPOSIT(acct_num);
break;
case 3:
MAKE_WITHDRAWAL(acct_num);
break;
case 4:
MAKE_TRANSFER(acct_num);
break;
case 5:
exit_early = MAKE_QUICK_WITHDRAWAL(acct_num);
if (exit_early)
{
session = FALSE; /* end session after quick withdrawal */
} /* unless it's an overdraft */
break;
case 0:
session = FALSE;
break;
default:
DISPLAY("\nInvalid choice.\n");
break;
} /* end of switch */
} /* end of while (session) */
if (user)
{ END_USER_SESSION(); } /* finish this user */
} /* end of while (user) */
END_ATM();
exit (0);
}
/*-----------------------------------------------------------------------------
INIT_ATM
Session-wide settings: input and output, Trace initialization, database
-----------------------------------------------------------------------------*/
void INIT_ATM (argc, argv)
int argc;
char *argv[];
{
long status;
char user_pass[40];
/******************************************************************************
Set up input and output files
******************************************************************************/
if (argc == 1) /* no input file; use stdin, stdout */
{ FromFile = FALSE; }
if (argc == 2)
{
if (argv[1] == NULL)
{ printf("Input filename is NULL\n"); }
else
{
printf("Input filename is %s\n", argv[1]);
if ((InFile = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "Can't open file %s\n", argv[1]);
exit(1);
}
else /* we have an input file */
{ FromFile = TRUE; }
}
}
if (argc > 2)
{
fprintf(stderr, "Too many arguments on command line\n");
exit(1);
}
/******************************************************************************
Initialize Trace session and start collection
******************************************************************************/
strcpy(Version, "V1.0");
strcpy(Collection_Name, "sampatm");
strcpy(FDF_Name, "atm.fdf");
status = epc_init(API_VERSION, VENDOR, FACILITY_NUMBER, Version, NULL, NULL,
&Event_Flags, MAX_EVENT, EPC_K_ALLOC, 0, 0, NULL, NULL);
if (status == epc_s_success)
status = epc_collect(API_VERSION, VENDOR, FACILITY_NUMBER, Version, 0,
Collection_Name, FDF_Name, 0, 0);
if (status != epc_s_success)
exit(status); /* problem with Trace */
/******************************************************************************
Connect to database;
******************************************************************************/
strcpy(user_pass, "atm/sampleatm");
EXEC SQL CONNECT :user_pass;
EXEC SQL ROLLBACK; /* rollback any default trans */
return;
}
/*-----------------------------------------------------------------------------
END_ATM
Clean up session: close files, end Trace collection, exit database
-----------------------------------------------------------------------------*/
void END_ATM ()
{
long status;
if (FromFile)
{ fclose(InFile); }
EXEC SQL SET TRANSACTION READ ONLY;
EXEC SQL COMMIT RELEASE;
status = epc_cancel(API_VERSION, VENDOR, FACILITY_NUMBER, Version, Collection_Name, 0);
return;
}
/*-----------------------------------------------------------------------------
LOGIN_USER
Get account number from user and validate against database
-----------------------------------------------------------------------------*/
long LOGIN_USER ()
{
char good_input;
char line[MAXLINE];
long acct_num;
long valid;
long status;
char *record; /* event record */
good_input = FALSE;
record = malloc(S_LONG);
DISPLAY("\n\n Trace Manhattan Bank\n");
DISPLAY("Automated Teller Machine\n\n\n");
DISPLAY("Please enter your account number\n");
DISPLAY("or enter 0 to exit: ");
do
{
READ(line);
acct_num = atoi(line);
if (acct_num == 0) /* allow user to exit without */
{ good_input = TRUE; } /* logging in */
else
{
valid = ATM_VALID_ACCT_NUM(acct_num); /* valid acct num or -1 */
if (valid == -1) /* no account in database */
{
if (Event_Flags[VALIDATION_ERR])
{
memcpy(record, &acct_num, S_LONG);
status = epc_event(API_VERSION, VENDOR, FACILITY_NUMBER,
VALIDATION_ERR, 0, record, S_LONG, 0, 0, 0);
}
DISPLAY("\nInvalid account number. Enter your account number");
DISPLAY("\nor enter 0 to exit: ");
}
else /* account in database */
{
if (Event_Flags[VALIDATION_OK])
{
memcpy(record, &acct_num, S_LONG);
status = epc_event(API_VERSION, VENDOR, FACILITY_NUMBER,
VALIDATION_OK, 0, record, S_LONG, 0, 0, 0);
}
good_input = TRUE;
}
}
} while (!good_input);
free(record);
return (acct_num);
}
/*-----------------------------------------------------------------------------
INIT_USER_SESSION
Start user_session event
-----------------------------------------------------------------------------*/
void INIT_USER_SESSION ()
{
long status;
if (Event_Flags[USER_SESSION])
{
status = epc_start_event(API_VERSION, VENDOR, FACILITY_NUMBER,
USER_SESSION, &Session_Handle, 0, NULL,
0, 0, 0, 0);
}
return;
}
/*-----------------------------------------------------------------------------
END_USER_SESSION
End user_session event
-----------------------------------------------------------------------------*/
void END_USER_SESSION ()
{
long status;
/* Make sure cross_fac_1 gets reset now that we're done */
status = epc_cf_value(API_VERSION, 1, 0, NULL, NULL);
if (Event_Flags[USER_SESSION])
{
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER, USER_SESSION,
&Session_Handle, 0, NULL, 0, 0, 0, 0);
}
return;
}
/*-----------------------------------------------------------------------------
DISPLAY_MAIN_MENU
Display main menu and get user's choice
-----------------------------------------------------------------------------*/
long DISPLAY_MAIN_MENU ()
{
char line[MAXLINE];
long choice;
char good_input;
good_input = FALSE;
DISPLAY("\n\nTrace Manhattan Bank\n");
DISPLAY(" ATM Main Menu\n");
DISPLAY("1. Balance\n");
DISPLAY("2. Deposit\n");
DISPLAY("3. Withdrawal\n");
DISPLAY("4. Transfer\n");
DISPLAY("5. Quick Withdrawal $50\n\n");
DISPLAY("0. Exit\n\n");
DISPLAY("Enter choice: ");
do
{
READ(line);
choice = atoi(line);
if ((choice > -1) && (choice < 6))
{
good_input = TRUE;
}
else
DISPLAY("\nInvalid choice. Enter choice: ");
} while (!good_input); /* end of do */
return (choice);
}
/*-----------------------------------------------------------------------------
GET_BALANCES
Display balances of savings and checkings acct
-----------------------------------------------------------------------------*/
void GET_BALANCES (acct_num)
long acct_num;
{
long status;
float sav_amt;
float chk_amt;
char line[MAXLINE];
strcpy(Regist_ID, "Balances");
status = epc_cf_value(API_VERSION, 1, BALANCES, NULL, NULL);
status = epc_add_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER, Version,
Regist_ID, 1);
if (Event_Flags[BALANCES])
{
status = epc_start_event(API_VERSION, VENDOR, FACILITY_NUMBER, BALANCES,
&Txn_Handle, 0, NULL, 0, 0, 0, 0);
}
ATM_START_RO();
sav_amt = ATM_SAV_BALANCE (acct_num);
chk_amt = ATM_CHK_BALANCE (acct_num);
ATM_COMMIT();
if (Event_Flags[BALANCES])
{
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER, BALANCES,
&Txn_Handle, 0, NULL, 0, 0, 0, 0);
}
status = epc_remove_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER,
Version, Regist_ID, 1);
DISPLAY("\n\nAccount Balances\n\n");
if (!FromFile)
{
printf("Checking: %-.2f\n", chk_amt);
printf("Savings : %-.2f\n", sav_amt);
}
DISPLAY("\nPress ENTER to return to Main Menu: ");
READ(line);
return;
}
/*-----------------------------------------------------------------------------
MAKE_DEPOSIT
Deposit money into either savings or checkings.
-----------------------------------------------------------------------------*/
void MAKE_DEPOSIT (acct_num)
long acct_num;
{
char line[MAXLINE];
long acct_type;
char good_choice;
char good_amount;
long txn_amt = 0;
long status;
char *record;
good_choice = FALSE;
good_amount = FALSE;
record = malloc(S_LONG);
strcpy(Regist_ID, "Deposit");
status = epc_cf_value(API_VERSION, 1, DEPOSIT, NULL, NULL);
status = epc_add_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER, Version,
Regist_ID, 1);
DISPLAY("\n\nAccount Deposit\n\n");
DISPLAY("Deposit into:\n");
DISPLAY("1. Checking\n");
DISPLAY("2. Savings\n");
DISPLAY("\nEnter choice or 0 to cancel: ");
do
{
READ(line);
acct_type = atoi(line);
if ((acct_type < 0) || (acct_type > 2)) /* bad input */
{ DISPLAY("\nInvalid choice. Enter choice: "); }
else
{ good_choice = TRUE; } /* valid account type */
} while (!good_choice); /* end of do */
if (acct_type == 0) /* cancel transaction */
{
txn_amt = 0;
good_amount = TRUE;
}
while (!good_amount)
{
DISPLAY("\nEnter dollar amount to deposit or 0 to cancel: ");
READ(line);
txn_amt = atoi(line);
if (txn_amt < 0)
{ DISPLAY("\nInvalid amount."); }
else
{ good_amount = TRUE; }
}
if (txn_amt > 0)
{
if (Event_Flags[DEPOSIT])
{
memset(record, 0, S_LONG);
status = epc_start_event(API_VERSION, VENDOR, FACILITY_NUMBER, DEPOSIT,
&Txn_Handle, 0, record, S_LONG,
0, 0, 0);
}
ATM_START_RW();
if (acct_type == 1)
{ ATM_CHK_DEPOSIT(acct_num, txn_amt); }
if (acct_type == 2)
{ ATM_SAV_DEPOSIT(acct_num, txn_amt); }
ATM_COMMIT();
if (Event_Flags[DEPOSIT])
{
memcpy(record, &txn_amt, S_LONG);
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER, DEPOSIT,
&Txn_Handle, 0, record, S_LONG, 0, 0, 0);
}
}
status = epc_remove_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER,
Version, Regist_ID, 1);
free(record);
return;
}
/*-----------------------------------------------------------------------------
MAKE_WITHDRAWAL
Withdraw money from either savings or checkings. If withdrawal is more
than balance, record an overdraft event
-----------------------------------------------------------------------------*/
void MAKE_WITHDRAWAL (acct_num)
long acct_num;
{
long status;
char line[MAXLINE];
char txn_complete;
long acct_type;
char good_choice;
long txn_amt = 0;
char good_amount;
float acct_bal;
char *wrecord, *orecord; /* event records for withdrawal, overdraft */
txn_complete = FALSE;
wrecord = malloc(S_LONG);
orecord = malloc(S_LONG);
strcpy(Regist_ID, "Withdrawal");
status = epc_cf_value(API_VERSION, 1, WITHDRAWAL, NULL, NULL);
status = epc_add_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER, Version,
Regist_ID, 1);
do /* get transaction input */
{
good_choice = FALSE;
DISPLAY("\n\nAccount Withdrawal\n\n");
DISPLAY("Withdraw from:\n");
DISPLAY("1. Checking\n");
DISPLAY("2. Savings\n");
DISPLAY("\nEnter choice or 0 to cancel: ");
do /* get account type */
{
READ(line);
acct_type = atoi(line);
if ((acct_type < 0) || (acct_type > 2)) /* bad input */
{ DISPLAY("\nInvalid choice. Enter choice: "); }
else
{ good_choice = TRUE; } /* valid account type */
} while (!good_choice);
if (acct_type == 0) /* cancel transaction */
{
txn_amt = 0;
good_amount = TRUE;
}
else
{ good_amount = FALSE; } /* need to get amount */
while (!good_amount)
{
DISPLAY("\nEnter dollar amount to withdraw or 0 to cancel: ");
READ(line);
txn_amt = atoi(line);
if (txn_amt < 0)
{ DISPLAY("\nInvalid amount."); }
else
{ good_amount = TRUE; }
} /* have good amount */
if (txn_amt > 0) /* user didn't cancel */
{
if (Event_Flags[WITHDRAWAL])
{
memset(wrecord, 0, S_LONG);
status = epc_start_event(API_VERSION, VENDOR, FACILITY_NUMBER,
WITHDRAWAL, &Txn_Handle, 0, wrecord,
S_LONG, 0, 0, 0);
}
ATM_START_RW();
if (acct_type == 1)
{ acct_bal = ATM_CHK_BALANCE(acct_num); }
if (acct_type == 2)
{ acct_bal = ATM_SAV_BALANCE(acct_num); }
if (acct_bal > txn_amt) /* sufficient funds */
{
if (acct_type == 1)
{ ATM_CHK_WITHDRAWAL(acct_num, txn_amt, acct_bal); }
if (acct_type == 2)
{ ATM_SAV_WITHDRAWAL(acct_num, txn_amt, acct_bal); }
ATM_COMMIT();
txn_complete = TRUE;
if (Event_Flags[WITHDRAWAL])
{
memcpy(wrecord, &txn_amt, S_LONG);
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER,
WITHDRAWAL, &Txn_Handle, 0, wrecord,
S_LONG, 0, 0, 0);
}
}
else
/* Record an overdraft; end the Withdrawal event with a txn_amt of 0 */
/* to show that a transaction really didn't happen */
{
ATM_ROLLBACK; /* cancel transaction */
if (Event_Flags[OVERDRAFT])
{
memcpy(orecord, &txn_amt, S_LONG);
status = epc_event(API_VERSION, VENDOR, FACILITY_NUMBER,
OVERDRAFT, 0, orecord, S_LONG, 0, 0, 0);
}
if (Event_Flags[WITHDRAWAL])
{
memset(wrecord, 0, S_LONG);
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER,
WITHDRAWAL, &Txn_Handle, 0, wrecord,
S_LONG, 0, 0, 0);
}
DISPLAY("\nBalance insufficient for withdrawal\n");
}
}
else /* txn_amt = 0, cancel */
txn_complete = TRUE;
} while (!txn_complete); /* end of do */
status = epc_remove_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER,
Version, Regist_ID, 1);
free(wrecord);
free(orecord);
return;
}
/*-----------------------------------------------------------------------------
MAKE_TRANSFER
Transfer money from one account to other. Destination account might not
be in this bank.
-----------------------------------------------------------------------------*/
void MAKE_TRANSFER (acct_num)
long acct_num;
{
long status;
char line[MAXLINE];
char txn_complete;
char good_source;
long acct_type;
char good_amount;
long txn_amt = 0;
long dest_num;
char good_dest;
long dest_type;
float acct_bal;
char *trecord, *orecord; /* event records for transfer, overdraft */
char *t_ptr; /* pointer to trecord */
txn_complete = FALSE;
trecord = malloc(S_LONG + S_LONG);
orecord = malloc(S_LONG);
strcpy(Regist_ID, "Transfer");
status = epc_cf_value(API_VERSION, 1, TRANSFER, NULL, NULL);
status = epc_add_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER, Version,
Regist_ID, 1);
do
{
DISPLAY("\n\nAccount Transfer\n\n");
DISPLAY("Transfer from:\n");
DISPLAY("1. Checking\n");
DISPLAY("2. Savings\n");
DISPLAY("\nEnter choice or 0 to cancel: ");
good_source = FALSE;
do /* get account type */
{
READ(line);
acct_type = atoi(line);
if ((acct_type < 0) || (acct_type > 2)) /* bad input */
{ DISPLAY("\nInvalid choice. Enter choice: "); }
else
{ good_source = TRUE; } /* valid account type */
} while (!good_source);
if (acct_type == 0) /* cancel transaction */
{ return; }
good_amount = FALSE;
while (!good_amount)
{
DISPLAY("\nEnter dollar amount to transfer or 0 to cancel: ");
READ(line);
txn_amt = atoi(line);
if (txn_amt < 0)
{ DISPLAY("\nInvalid amount."); }
if (txn_amt > 0)
{ good_amount = TRUE; }
if (txn_amt == 0) /* cancel transaction */
{ return; }
}
DISPLAY("\nEnter destination account number or 0 to cancel: ");
READ(line);
dest_num = atoi(line);
if (dest_num == 0) /* cancel transaction */
{ return; }
DISPLAY("\nTransfer to:\n");
DISPLAY("1. Checking\n");
DISPLAY("2. Savings\n");
DISPLAY("\nEnter choice or 0 to cancel: ");
good_dest = FALSE;
do /* get account type for */
{ /* destination account */
READ(line);
dest_type = atoi(line);
if ((dest_type < 0) || (dest_type > 2)) /* bad input */
{ DISPLAY("\nInvalid choice. Enter choice: "); }
else
{ good_dest = TRUE; } /* valid account type */
} while (!good_dest);
if (dest_type == 0) /* cancel transaction */
{ return; }
/*----------------------------------------------------------------------------
Now we have good source, destination, amount
-----------------------------------------------------------------------------*/
if (Event_Flags[TRANSFER])
{
t_ptr = trecord;
memset(t_ptr, 0, S_LONG);
t_ptr += S_LONG;
memcpy(t_ptr, &dest_num, S_LONG);
status = epc_start_event(API_VERSION, VENDOR, FACILITY_NUMBER,
TRANSFER, &Txn_Handle, 0, trecord,
(S_LONG + S_LONG), 0, 0, 0);
}
ATM_START_RW();
if (acct_type == 1)
{ acct_bal = ATM_CHK_BALANCE(acct_num); }
if (acct_type == 2)
{ acct_bal = ATM_SAV_BALANCE(acct_num); }
if (acct_bal > txn_amt) /* sufficient funds */
{
if (acct_type == 1)
{ ATM_CHK_WITHDRAWAL(acct_num, txn_amt, acct_bal); }
if (acct_type == 2)
{ ATM_SAV_WITHDRAWAL(acct_num, txn_amt, acct_bal); }
/* Returns 0 if the account number is not for this branch of the bank */
dest_num = ATM_VALID_XFER_ACCT(dest_num);
if (dest_num)
{
if (dest_type == 1)
{ ATM_CHK_DEPOSIT(dest_num, txn_amt); }
if (dest_type == 2)
{ ATM_SAV_DEPOSIT(dest_num, txn_amt); }
}
ATM_COMMIT();
if (Event_Flags[TRANSFER])
{
t_ptr = trecord;
memcpy(t_ptr, &txn_amt, S_LONG);
t_ptr += S_LONG;
memcpy(t_ptr, &dest_num, S_LONG);
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER,
TRANSFER, &Txn_Handle, 0, trecord,
(S_LONG + S_LONG), 0, 0, 0);
}
txn_complete = TRUE;
}
else /* overdraft */
{
ATM_ROLLBACK; /* cancel transaction */
if (Event_Flags[OVERDRAFT])
{
memcpy(orecord, &txn_amt, S_LONG);
status = epc_event(API_VERSION, VENDOR, FACILITY_NUMBER, OVERDRAFT,
0, orecord, S_LONG, 0, 0, 0);
}
if (Event_Flags[TRANSFER])
{
t_ptr = trecord;
memset(t_ptr, 0, S_LONG);
t_ptr += S_LONG;
memcpy(t_ptr, &dest_num, S_LONG);
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER,
TRANSFER, &Txn_Handle, 0, trecord,
(S_LONG + S_LONG), 0, 0, 0);
}
DISPLAY("\nInsufficient funds.\n");
}
} while (!txn_complete);
status = epc_remove_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER,
Version, Regist_ID, 1);
free(trecord);
free(orecord);
return;
}
/*-----------------------------------------------------------------------------
MAKE_QUICK_WITHDRAWAL
Withdraw $50 from checking. If withdrawal is more than balance, record
an overdraft event.
-----------------------------------------------------------------------------*/
long MAKE_QUICK_WITHDRAWAL (acct_num)
long acct_num;
{
long status;
float chk_bal;
long good_txn;
long txn_amt = 50;
char *qrecord, *orecord;
qrecord = malloc(S_LONG);
orecord = malloc(S_LONG);
strcpy(Regist_ID, "Quick Withdrawal");
status = epc_cf_value(API_VERSION, 1, QUICK_WITHDRAW, NULL, NULL);
status = epc_add_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER, Version,
Regist_ID, 1);
if (Event_Flags[QUICK_WITHDRAW])
{
memset(qrecord, 0, S_LONG);
status = epc_start_event(API_VERSION, VENDOR, FACILITY_NUMBER,
QUICK_WITHDRAW, &Txn_Handle, 0, qrecord,
S_LONG, 0, 0, 0);
}
ATM_START_RW();
chk_bal = ATM_CHK_BALANCE(acct_num);
if (chk_bal > 50) /* sufficient funds */
{
ATM_CHK_WITHDRAWAL(acct_num, txn_amt, chk_bal);
ATM_COMMIT();
if (Event_Flags[QUICK_WITHDRAW])
{
memcpy(qrecord, &txn_amt, S_LONG);
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER,
QUICK_WITHDRAW, &Txn_Handle, 0, qrecord,
S_LONG, 0, 0, 0);
}
good_txn = TRUE;
}
else /* overdraft */
{
ATM_ROLLBACK; /* cancel transaction */
if (Event_Flags[OVERDRAFT])
{
memcpy(orecord, &txn_amt, S_LONG);
status = epc_event(API_VERSION, VENDOR, FACILITY_NUMBER, OVERDRAFT,
0, orecord, S_LONG, 0, 0, 0);
}
if (Event_Flags[QUICK_WITHDRAW])
{
memset(qrecord, 0, S_LONG);
status = epc_end_event(API_VERSION, VENDOR, FACILITY_NUMBER,
QUICK_WITHDRAW, &Txn_Handle, 0, qrecord,
S_LONG, 0, 0, 0);
}
DISPLAY("\nInsufficient funds.\n");
good_txn = FALSE;
}
status = epc_remove_reg_id(API_VERSION, VENDOR, FACILITY_NUMBER,
Version, Regist_ID, 1);
free(qrecord);
free(orecord);
return (good_txn);
}
/*-----------------------------------------------------------------------------
ATM_VALID_ACCT_NUM
Return acct_num if found in database; otherwise, return -1
-----------------------------------------------------------------------------*/
long ATM_VALID_ACCT_NUM (acct_num)
long acct_num;
{
EXEC SQL BEGIN DECLARE SECTION;
long sav_acct_num = -1;
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT account_number INTO :sav_acct_num
FROM savings WHERE account_number = :acct_num;
return (sav_acct_num);
}
/*-----------------------------------------------------------------------------
ATM_VALID_XFER_ACCT
Return acct_num if found in database; otherwise, return 0
-----------------------------------------------------------------------------*/
long ATM_VALID_XFER_ACCT (acct_num)
long acct_num;
{
char acct_found = FALSE;
char stop_looking = FALSE;
EXEC SQL BEGIN DECLARE SECTION;
long sav_acct_num;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE xfer_acct_cursor CURSOR FOR
SELECT account_number FROM savings;
EXEC SQL OPEN xfer_acct_cursor;
while (!stop_looking)
{
EXEC SQL FETCH xfer_acct_cursor INTO :sav_acct_num;
if (sav_acct_num == acct_num)
{
acct_found = TRUE;
stop_looking = TRUE;
}
if (SQLCODE > 0) /* end of cursor */
{
stop_looking = TRUE;
}
}
EXEC SQL CLOSE xfer_acct_cursor;
if (acct_found)
{ return(sav_acct_num); }
else
{ return (0); }
}
/*-----------------------------------------------------------------------------
ATM_SAV_BALANCE
Return savings account balance for account number
-----------------------------------------------------------------------------*/
float ATM_SAV_BALANCE (acct_num)
long acct_num;
{
EXEC SQL BEGIN DECLARE SECTION;
float sav_bal = 0;
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT balance INTO :sav_bal
FROM savings WHERE account_number = :acct_num;
return (sav_bal);
}
/*-----------------------------------------------------------------------------
ATM_CHK_BALANCE
Return checking account balance for account number
-----------------------------------------------------------------------------*/
float ATM_CHK_BALANCE (acct_num)
long acct_num;
{
EXEC SQL BEGIN DECLARE SECTION;
float chk_bal = 0;
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT balance INTO :chk_bal
FROM checking WHERE account_number = :acct_num;
return (chk_bal);
}
/*-----------------------------------------------------------------------------
ATM_SAV_DEPOSIT
Add amount to balance in savings account
-----------------------------------------------------------------------------*/
void ATM_SAV_DEPOSIT (acct_num, amount)
long acct_num;
long amount;
{
EXEC SQL BEGIN DECLARE SECTION;
float prev_bal;
EXEC SQL END DECLARE SECTION;
prev_bal = ATM_SAV_BALANCE(acct_num);
EXEC SQL UPDATE savings SET balance = (:prev_bal + :amount)
WHERE account_number = :acct_num;
}
/*-----------------------------------------------------------------------------
ATM_CHK_DEPOSIT
Add amount to balance in checking account
-----------------------------------------------------------------------------*/
void ATM_CHK_DEPOSIT (acct_num, amount)
long acct_num;
long amount;
{
EXEC SQL BEGIN DECLARE SECTION;
float prev_bal;
EXEC SQL END DECLARE SECTION;
prev_bal = ATM_CHK_BALANCE(acct_num);
EXEC SQL UPDATE checking SET balance = (:prev_bal + :amount)
WHERE account_number = :acct_num;
}
/*-----------------------------------------------------------------------------
ATM_SAV_WITHDRAWAL
Subtract amount from balance in savings account; assumes amount is less
than balance (we checked balance before calling)
-----------------------------------------------------------------------------*/
void ATM_SAV_WITHDRAWAL (acct_num, amount, prev_bal)
long acct_num;
long amount;
float prev_bal;
{
EXEC SQL UPDATE savings SET balance = (:prev_bal - :amount)
WHERE account_number = :acct_num;
}
/*-----------------------------------------------------------------------------
ATM_CHK_WITHDRAWAL
Subtract amount from balance in checking account; assumes amount is less
than balance (we checked balance before calling)
-----------------------------------------------------------------------------*/
void ATM_CHK_WITHDRAWAL (acct_num, amount, prev_bal)
long acct_num;
long amount;
float prev_bal;
{
EXEC SQL UPDATE checking SET balance = (:prev_bal - :amount)
WHERE account_number = :acct_num;
}
/*-----------------------------------------------------------------------------
ATM_START_RW
Start read-write transaction
-----------------------------------------------------------------------------*/
void ATM_START_RW ()
{
EXEC SQL SET TRANSACTION READ WRITE;
}
/*-----------------------------------------------------------------------------
ATM_START_RO
Start read-only transaction
-----------------------------------------------------------------------------*/
void ATM_START_RO ()
{
EXEC SQL SET TRANSACTION READ ONLY;
}
/*-----------------------------------------------------------------------------
ATM_COMMIT
Commit transaction
-----------------------------------------------------------------------------*/
void ATM_COMMIT ()
{
EXEC SQL COMMIT;
}
/*-----------------------------------------------------------------------------
ATM_ROLLBACK
Rollback transaction
-----------------------------------------------------------------------------*/
void ATM_ROLLBACK ()
{
EXEC SQL ROLLBACK;
}
![]() ![]() Prev Next |
![]() Copyright © 1996 Oracle Corporation. All Rights Reserved. |
![]() Library |
![]() Product |
![]() Contents |
![]() Index |