DSN8DLRV
Prompts the user to choose an employee, then retrieves the resume data for that employee from the RESUME (CLOB) column of the EMP_PHOTO_RESUME table into a CLOB locator, uses LOB locator-handling functions to locate and break out data elements, and puts them in fields for display by ISPF.
/*********************************************************************
* Module name = DSN8DLRV (DB2 sample program) *
* *
* DESCRIPTIVE NAME = Display the resume of a specified employee *
* *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5675-DB2 *
* (C) COPYRIGHT 1982, 2000 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 7 *
* *
* Function: Prompts the user to choose an employee, then retrieves *
* the resume data for that employee from the RESUME (CLOB) *
* column of the EMP_PHOTO_RESUME table into a CLOB locator,*
* uses LOB locator-handling functions to locate and break *
* out data elements, and puts them in fields for display *
* by ISPF. *
* *
* Notes: *
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: IBM C/C++ for OS/390 V1R3 or subsequent release *
* Module size: See linkedit output *
* Attributes: Re-entrant and re-usable *
* *
* Entry Point: CEESTART (Language Environment entry point) *
* Purpose: See Function *
* Linkage: Standard MVS program invocation, no parameters *
* *
* Normal Exit: Return Code = 0000 *
* - Message: none *
* *
* Error Exit: Return Code = 0008 *
* - Message: *** ERROR: DSN8DLRV DB2 Sample Program *
* Unexpected SQLCODE encountered *
* at location xxx *
* Error detailed below *
* Processing terminated *
* (DSNTIAR-formatted message here)*
* *
* - Message: *** ERROR: DSN8DLRV DB2 Sample Program *
* No entry in the Employee Photo/ *
* Resume table for employee with *
* empno = xxxxxx *
* Processing terminated *
* *
* - Message: *** ERROR: DSN8DLRV DB2 Sample Program *
* No resume data exists in *
* the Employee Photo/Resume table *
* for the employee with empno = *
* xxxxxx. *
* Processing terminated *
* *
* *
* External References: *
* - Routines/Services: DSNTIAR, ISPF *
* - Data areas : DSNTIAR error_message *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8DLRV: *
* - Call initISPFvars to establish ISPF variable sharing *
* - Do until the user indicates termination *
* - Call clearISPFvars to reset the ISPF shared variables *
* - Call getEmplNum to request an employee id *
* - Call getEmplResume to retrieve the resume *
* - Call formatEmplResume to populate the ISPF display panel *
* - Call showEmplResume to display the resume *
* - Call freeISPFvars to terminate ISPF variable sharing *
* End DSN8DLRV *
* *
* initISPFvars: *
* - Establish ISPF variable sharing *
* End initISPFvars *
* *
* clearISPFvars: *
* - Set ISPF vars to blank if character type or 0 if numeric *
* End clearISPFvars *
* *
* getEmplNum: *
* - prompt user to select an employee whose resume is to be viewed *
* End getEmplNum *
* *
* getEmplResume: *
* - Fetch the specified employee's resume from DB2 using a CLOB *
* locator *
* End getEmplResume *
* *
* formatEmplResume: *
* - call getPersonalData to extract personal data from the resume *
* - call getDepartmentData to extract department data *
* - call getEducationData to extract education data *
* - call getWorkHistoryData to extract work history data *
* End formatEmplResume *
* *
* showEmplResume: *
* - Display the ISPF panel with the specified employee's resume *
* End showEmplResume *
* *
* freeISPFvars: *
* - Terminate variable sharing with ISPF *
* End freeISPFvars *
* *
* getPersonalData: *
* - Parse the employee's name, address, home telephone no., *
* birthdate, sex, marital status, height, and weight into ISPF *
* display variables *
* End getPersonalData *
* *
* getDepartmentData: *
* - Parse the employee's department number, manager, job position, *
* work telephone no., and hire date into ISPF display variables. *
* End getDepartmentData *
* *
* getEducationData: *
* - Parse the employee's degree dates, descriptions, and schools *
* into ISPF display variables. *
* End getEducationData *
* *
* getWorkHistoryData: *
* - Parse the employee's job dates, titles, and descriptions into *
* ISPF display variables. *
* End getWorkHistoryData *
* *
* sql_error: *
* - call DSNTIAR to format an unexpected SQLCODE. *
* End sql_error *
* *
**********************************************************************
* Assumptions: *
* (1) Each employee has exactly 2 entries under "Education" *
* (2) Each employee has exactly 3 entries under "Work History" *
* (3) Each job description consists of a single sentence and that *
* sentence ends with a period and that period is the only *
* period in the sentence. *
*********************************************************************/
/******************* C Program Product Libraries ********************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/***************************** Equates ******************************/
#define NO 0 /* False */
#define YES 1 /* True */
#define NOT_OK 0 /* Run status indicator: Error*/
#define OK 1 /* Run status indicator: Good */
#define TIAR_DIM 10 /* Max no. of DSNTIAR msgs */
#define TIAR_LEN 80 /* Length of DSNTIAR messages */
/************************** Global Storage **************************/
int keepViewing = YES; /* User status */
int status = OK; /* Run status */
short int ISPFrc; /* For ISPF return code */
/******************** DB2 SQL Communication Area ********************/
EXEC SQL INCLUDE SQLCA;
/********************** DB2 Message Formatter ***********************/
struct error_struct { /* DSNTIAR message structure */
short int error_len;
char error_text[TIAR_DIM][TIAR_LEN];
} error_message = {TIAR_DIM * (TIAR_LEN)};
#pragma linkage(dsntiar, OS)
extern short int dsntiar( struct sqlca *sqlca,
struct error_struct *msg,
int *len );
/**************************** DB2 Tables ****************************/
EXEC SQL DECLARE EMP_PHOTO_RESUME TABLE
( EMPNO CHAR(06) NOT NULL,
EMP_ROWID ROWID,
PSEG_PHOTO BLOB( 500K ),
BMP_PHOTO BLOB( 100K ),
RESUME CLOB( 5K ) );
/************** DB2 Host and Null Indicator Variables ***************/
EXEC SQL BEGIN DECLARE SECTION;
char hvEMPNO[7]; /* host var for emp ser no. */
long int begSection; /* ptr to beg of resume sec'n */
char *begField; /* ptr to beg of fld in sec'n */
long int endSection; /* ptr to end of resume sec'n */
char *endField; /* ptr to end of fld in sec'n */
SQL TYPE IS CLOB(5K) hvRESUME; /* host var for RESUME CLOB */
char *phvRESUME; /* ptr to RESUME CLOB data */
short int niRESUME = 0; /* indic var for RESUME CLOB */
EXEC SQL END DECLARE SECTION;
/******************** DB2 LOB Locator Variables *********************/
EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE IS CLOB_LOCATOR clRESUME; /* CLOB loc for RESUME column */
EXEC SQL END DECLARE SECTION;
/*************************** ISPF Linkage ***************************/
#pragma linkage(isplink,OS)
/*************************** ISPF Syntax ****************************/
char CHAR[9] = "CHAR ";
char DISPLAY[9] = "DISPLAY ";
char VDEFINE[9] = "VDEFINE ";
char VGET[9] = "VGET ";
char VRESET[9] = "VRESET ";
/********************** ISPF Shared Variables ***********************/
char D8EMNAME[25]; /* employee's name */
char D8EMNUMB[7]; /* employee's serial number */
char D8EMADR1[25]; /* employee's address line 1 */
char D8EMDEPT[5]; /* employee's department */
char D8EMADR2[25]; /* employee's address line 2 */
char D8MGRNAM[22]; /* employee's manager's name */
char D8EMADR3[15]; /* employee's address line 3 */
char D8EMPOSN[22]; /* employee's job position */
char D8EMBORN[19]; /* employee's date of birth */
char D8EMPHON[15]; /* employee's home phone no. */
char D8EMSEX[7]; /* employee's gender */
char D8EMHIRE[11]; /* employee's hire date */
char D8EMHGT[6]; /* employee's height */
char D8EMWGT[9]; /* employee's weight */
char D8EMPMST[9]; /* employee's marital status */
char D8EMEDY1[5]; /* date of most recent degree */
char D8EMEDD1[35]; /* type of most recent degree */
char D8EMEDY2[5]; /* date of previous degree */
char D8EMEDD2[35]; /* type of previous degree */
char D8EMEDI1[35]; /* name of most recent school */
char D8EMEDI2[35]; /* name of previous school */
char D8EMWHD1[17]; /* dates of 1st previous job */
char D8EMWHJ1[63]; /* title of 1st previous job */
char D8EMWHT1[63]; /* descr. of 1st previous job */
char D8EMWHD2[17]; /* dates of 2nd previous job */
char D8EMWHJ2[63]; /* title of 2nd previous job */
char D8EMWHT2[63]; /* descr. of 2nd previous job */
char D8EMWHD3[17]; /* dates of 3rd previous job */
char D8EMWHJ3[63]; /* title of 3rd previous job */
char D8EMWHT3[63]; /* descr. of 3rd previous job */
/************************* Global Functions *************************/
int main( void ); /* main logic */
void initISPFvars( void ); /* establish ISPF vars */
void clearISPFvars( void ); /* blank/zero ISPF disp vars */
void getEmplNum( void ); /* prompt for employee ser no */
void getEmplResume( void ); /* get resume from database */
void formatEmplResume( void ); /* build display panel */
void getPersonalData( void ); /* get personal data from res */
void getDepartmentData( void ); /* get dept data from resume */
void getEducationData( void ); /* get educ data from resume */
void getWorkHistoryData( void ); /* get job hist from resume */
void showEmplResume( void ); /* display the ISPF panel */
void freeISPFvars( void ); /* drop ISPF vars */
void sql_error( char *locmsg ); /* generate SQL messages */
/*********************************************************************
**************************** main routine ****************************
*********************************************************************/
int main( void )
{
/*******************************************************************
* Establish variable sharing with ISPF *
*******************************************************************/
initISPFvars();
/*******************************************************************
* Display employee resumes until user indicates completion *
*******************************************************************/
keepViewing = YES;
while( keepViewing == YES )
{
clearISPFvars();
/***************************************************************
* prompt user to select employee whose resume is to be viewed *
***************************************************************/
getEmplNum();
if( keepViewing == YES && status == OK )
{
/***********************************************************
* retrieve the employee's resume from DB2 *
***********************************************************/
getEmplResume();
/***********************************************************
* if successful, format the resume on ISPF *
***********************************************************/
if( status == OK )
formatEmplResume();
/***********************************************************
* if successful, display the resume on ISPF *
***********************************************************/
if( status == OK )
showEmplResume();
/***********************************************************
* otherwise, exit this program *
***********************************************************/
else
keepViewing = NO;
}
}
/*******************************************************************
* Terminate variable sharing with ISPF *
*******************************************************************/
freeISPFvars();
} /* end main */
void initISPFvars( void )
/*********************************************************************
* Called by the main routine. Establishes variable sharing between *
* ISPF and this program. *
*********************************************************************/
{
ISPFrc = isplink( VDEFINE, "D8EMNAME", D8EMNAME, CHAR, 24 );
ISPFrc = isplink( VDEFINE, "D8EMNUMB", D8EMNUMB, CHAR, 6 );
ISPFrc = isplink( VDEFINE, "D8EMADR1", D8EMADR1, CHAR, 24 );
ISPFrc = isplink( VDEFINE, "D8EMDEPT", D8EMDEPT, CHAR, 4 );
ISPFrc = isplink( VDEFINE, "D8EMADR2", D8EMADR2, CHAR, 24 );
ISPFrc = isplink( VDEFINE, "D8MGRNAM", D8MGRNAM, CHAR, 21 );
ISPFrc = isplink( VDEFINE, "D8EMADR3", D8EMADR3, CHAR, 14 );
ISPFrc = isplink( VDEFINE, "D8EMPOSN", D8EMPOSN, CHAR, 21 );
ISPFrc = isplink( VDEFINE, "D8EMBORN", D8EMBORN, CHAR, 18 );
ISPFrc = isplink( VDEFINE, "D8EMPHON", D8EMPHON, CHAR, 14 );
ISPFrc = isplink( VDEFINE, "D8EMSEX ", D8EMSEX , CHAR, 6 );
ISPFrc = isplink( VDEFINE, "D8EMHIRE", D8EMHIRE, CHAR, 10 );
ISPFrc = isplink( VDEFINE, "D8EMHGT ", D8EMHGT , CHAR, 5 );
ISPFrc = isplink( VDEFINE, "D8EMWGT ", D8EMWGT , CHAR, 8 );
ISPFrc = isplink( VDEFINE, "D8EMPMST", D8EMPMST, CHAR, 8 );
ISPFrc = isplink( VDEFINE, "D8EMEDY1", D8EMEDY1, CHAR, 4 );
ISPFrc = isplink( VDEFINE, "D8EMEDD1", D8EMEDD1, CHAR, 34 );
ISPFrc = isplink( VDEFINE, "D8EMEDY2", D8EMEDY2, CHAR, 4 );
ISPFrc = isplink( VDEFINE, "D8EMEDD2", D8EMEDD2, CHAR, 34 );
ISPFrc = isplink( VDEFINE, "D8EMEDI1", D8EMEDI1, CHAR, 34 );
ISPFrc = isplink( VDEFINE, "D8EMEDI2", D8EMEDI2, CHAR, 34 );
ISPFrc = isplink( VDEFINE, "D8EMWHD1", D8EMWHD1, CHAR, 16 );
ISPFrc = isplink( VDEFINE, "D8EMWHJ1", D8EMWHJ1, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHT1", D8EMWHT1, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHD2", D8EMWHD2, CHAR, 16 );
ISPFrc = isplink( VDEFINE, "D8EMWHJ2", D8EMWHJ2, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHT2", D8EMWHT2, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHD3", D8EMWHD3, CHAR, 16 );
ISPFrc = isplink( VDEFINE, "D8EMWHJ3", D8EMWHJ3, CHAR, 62 );
ISPFrc = isplink( VDEFINE, "D8EMWHT3", D8EMWHT3, CHAR, 62 );
} /* end initISPFvars */
void clearISPFvars( void )
/*********************************************************************
* Called by the main routine. Blanks out the ISPF shared variables. *
*********************************************************************/
{
memset( D8EMNAME, 0, 25 );
memset( D8EMNUMB, 0, 7 );
memset( D8EMADR1, 0, 25 );
memset( D8EMDEPT, 0, 5 );
memset( D8EMADR2, 0, 25 );
memset( D8MGRNAM, 0, 22 );
memset( D8EMADR3, 0, 15 );
memset( D8EMPOSN, 0, 22 );
memset( D8EMBORN, 0, 19 );
memset( D8EMPHON, 0, 15 );
memset( D8EMSEX , 0, 7 );
memset( D8EMHIRE, 0, 11 );
memset( D8EMHGT , 0, 9 );
memset( D8EMWGT , 0, 8 );
memset( D8EMPMST, 0, 9 );
memset( D8EMEDY1, 0, 5 );
memset( D8EMEDD1, 0, 35 );
memset( D8EMEDY2, 0, 5 );
memset( D8EMEDD2, 0, 35 );
memset( D8EMEDI1, 0, 35 );
memset( D8EMEDI2, 0, 35 );
memset( D8EMWHD1, 0, 17 );
memset( D8EMWHJ1, 0, 63 );
memset( D8EMWHT1, 0, 63 );
memset( D8EMWHD2, 0, 17 );
memset( D8EMWHJ2, 0, 63 );
memset( D8EMWHT2, 0, 63 );
memset( D8EMWHD3, 0, 17 );
memset( D8EMWHJ3, 0, 63 );
memset( D8EMWHT3, 0, 63 );
} /* end clearISPFvars */
void getEmplNum( void )
/*********************************************************************
* Called by the main routine. Displays an ISPF panels to prompt the *
* user to select an employee whose resume is to be displayed. *
*********************************************************************/
{
/*******************************************************************
* Display the prompt panel *
*******************************************************************/
ISPFrc = isplink( "DISPLAY ","DSN8SSE " );
if( ISPFrc != 0 )
keepViewing = NO;
/*******************************************************************
* Save off the value of the ISPF shared variable *
*******************************************************************/
strcpy( hvEMPNO,D8EMNUMB );
} /* end getEmplNum */
void getEmplResume( void )
/*********************************************************************
* Called by the main routine. Extracts a specified employee's *
* resume data from a CLOB column in the sample EMP_PHOTO_RESUME *
* table to a CLOB locator. *
*********************************************************************/
{
/*******************************************************************
* Establish a CLOB locator on the resume of the specified empno *
*******************************************************************/
EXEC SQL SELECT RESUME
INTO :clRESUME
FROM EMP_PHOTO_RESUME
WHERE EMPNO = :hvEMPNO;
if( SQLCODE == 100 )
{
status = NOT_OK;
printf( "*************************************************\n" );
printf( "*** ERROR: DSN8DLRV DB2 Sample Program\n" );
printf( "*** No entry in the Employee Photo/Resume\n" );
printf( "*** table for employee with empno = %s\n",
hvEMPNO );
printf( "*** Processing terminated\n" );
printf( "*************************************************\n" );
}
else if( SQLCODE == -305 )
{
status = NOT_OK;
printf( "*************************************************\n" );
printf( "*** ERROR: DSN8DLRV DB2 Sample Program\n" );
printf( "*** No resume data exists in the\n" );
printf( "*** Employee Photo/Resume table for the\n" );
printf( "*** employee with empno = %s\n",
hvEMPNO );
printf( "*** Processing terminated\n" );
printf( "*************************************************\n" );
}
else if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "getEmplResume @ SELECT" );
}
} /* end getEmplResume */
void formatEmplResume( void )
/*********************************************************************
* Called by the main routine. Calls routines to parse out the *
* contents of the resume into ISPF-shared variables. *
*********************************************************************/
{
/*******************************************************************
* Get the employee's name, address, and other personal information *
*******************************************************************/
getPersonalData();
/*******************************************************************
* Get the employee's department no., manager, and other dept data *
*******************************************************************/
if( status == OK )
getDepartmentData();
/*******************************************************************
* Get the employee's education data *
*******************************************************************/
if( status == OK )
getEducationData();
/*******************************************************************
* Get the employee's employment history *
*******************************************************************/
if( status == OK )
getWorkHistoryData();
/*******************************************************************
* Free the CLOB locator for the resume *
*******************************************************************/
if( status == OK )
{
EXEC SQL FREE LOCATOR :clRESUME;
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "formatEmplResume @ FREE LOCATOR" );
}
}
} /* end formatEmplResume */
void getPersonalData( void )
/*********************************************************************
* Called by the formatEmplResume routine to parse the CLOB locator *
* data for the employee's name, address, home telephone no., birth- *
* date, sex, marital status, height, and weight into ISPF variables. *
*********************************************************************/
{
/*******************************************************************
* Extract the Personal Data section from the CLOB locator *
*******************************************************************/
EXEC SQL SET :begSection /* locate start of pers. data */
= POSSTR( :clRESUME, ' Resume: ' );
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "getPersonalData @ POSSTR 1" );
}
if( status == OK )
{
EXEC SQL SET :endSection /* locate start of dept. data */
= POSSTR( :clRESUME, ' Department Information ' );
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "getPersonalData @ POSSTR 2" );
}
}
if( status == OK )
{
EXEC SQL SET :hvRESUME /* extract what's in between */
= SUBSTR( :clRESUME, :begSection, :endSection-:begSection );
if( SQLCODE == 0 )
hvRESUME.data[hvRESUME.length] = '\0';
else
{
status = NOT_OK;
sql_error( "getPersonalData @ SUBSTR" );
}
}
/*******************************************************************
* Get the employee's name *
*******************************************************************/
if( status == OK )
{
phvRESUME = &hvRESUME.data[0]; /* set pointer to the data */
begField /* find Resume: label */
= strstr( phvRESUME," Resume: " );
begField = begField + 11; /* skip past label */
endField /* find Personal Inf... label */
= strstr( phvRESUME," Personal Information " );
strncpy( D8EMNAME, /* get name from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's street address *
*******************************************************************/
if( status == OK )
{
begField /* find Address: label */
= strstr( phvRESUME," Address: " );
begField = begField + 22; /* skip past label */
endField /* find end of street addr */
= strstr( phvRESUME," " );
strncpy( D8EMADR1, /* get addr from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's city, state, and zipcode *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to city/st/zip dat */
endField /* find end of ciy/st/zip */
= strstr( phvRESUME," Phone: " );
strncpy( D8EMADR2, /* get data from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's home telephone number *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to home phone data */
endField /* find end of home phone no. */
= strstr( phvRESUME," Birthdate: " );
strncpy( D8EMADR3, /* get phone# from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's birthdate *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to birthdate data */
endField /* find end of birthdate data */
= strstr( phvRESUME," Sex: " );
strncpy( D8EMBORN, /* get birthdate from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's sex *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to sex data */
endField /* find end of sex data */
= strstr( phvRESUME," Marital Status: " );
strncpy( D8EMSEX, /* get sex data from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's marital status *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to marital status */
endField /* find end of marital stat. */
= strstr( phvRESUME," Height: " );
strncpy( D8EMPMST, /* get mar stat from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's height *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to height data */
endField /* find end of height data */
= strstr( phvRESUME," Weight: " );
strncpy( D8EMHGT, /* get height from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's weight *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to weight data */
strcpy( D8EMWGT, /* weight is at end of string */
begField );
}
} /* end getPersonalData */
void getDepartmentData( void )
/*********************************************************************
* Called by the formatEmplResume routine to parse the CLOB locator *
* data for the employee's department number, manager, job position, *
* work telephone no., and hire date into ISPF variables. *
*********************************************************************/
{
/*******************************************************************
* Extract the Department Data section from the CLOB locator *
*******************************************************************/
begSection = endSection; /* Locate start of Dept data */
EXEC SQL SET :endSection /* Locate start of Educ data */
= POSSTR( :clRESUME, ' Education ' );
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "getDepartmentData @ POSSTR" );
}
if( status == OK )
{
EXEC SQL SET :hvRESUME /* extract what's in between */
= SUBSTR( :clRESUME, :begSection, :endSection-:begSection );
if( SQLCODE == 0 )
hvRESUME.data[hvRESUME.length] = '\0';
else
{
status = NOT_OK;
sql_error( "getDepartmentData @ SUBSTR" );
}
}
/*******************************************************************
* Get the employee's department number *
*******************************************************************/
if( status == OK )
{
phvRESUME = &hvRESUME.data[0]; /* set pointer to the data */
begField /* find Dept Number: label */
= strstr( phvRESUME," Dept Number: " );
begField = begField + 22; /* skip past label */
endField /* find end of dept. no. */
= strstr( phvRESUME," Manager: " );
strncpy( D8EMDEPT, /* get dept# from in between */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's manager's name *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to manager data */
endField /* find end of manager */
= strstr( phvRESUME," Position: " );
strncpy( D8MGRNAM, /* get mgr name from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's job position *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to position data */
phvRESUME = begField; /* skip ahead in buffer */
endField /* find end of position data */
= strstr( phvRESUME," Phone: " );
strncpy( D8EMPOSN, /* get position from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's work telephone number *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to work phone data */
endField /* find end of work phone no. */
= strstr( phvRESUME," Hire Date: " );
strncpy( D8EMPHON, /* get work ph# from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get the employee's hire date *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to hire date data */
strcpy( D8EMHIRE, /* hire data is at end of str */
begField );
}
} /* end getDepartmentData */
void getEducationData( void )
/*********************************************************************
* Called by the formatEmplResume routine to parse the CLOB locator *
* data for the employee's degree dates, descriptions, and schools *
* into ISPF variables. *
*********************************************************************/
{
/*******************************************************************
* Extract the Education Data section from the CLOB locator *
*******************************************************************/
begSection = endSection; /* Locate start of Educ data */
EXEC SQL SET :endSection /* Locate start of Work Hist */
= POSSTR( :clRESUME, ' Work History ' );
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "getEducationData @ POSSTR" );
}
if( status == OK )
{
EXEC SQL SET :hvRESUME /* extract what's in between */
= SUBSTR( :clRESUME, :begSection, :endSection-:begSection );
if( SQLCODE == 0 )
hvRESUME.data[hvRESUME.length] = '\0';
else
{
status = NOT_OK;
sql_error( "getEducationData @ SUBSTR" );
}
}
/*******************************************************************
* Get year and description of employee's most recent degree *
*******************************************************************/
if( status == OK )
{
phvRESUME = &hvRESUME.data[0]; /* set pointer to the data */
begField /* find Education label */
= strstr( phvRESUME," Education " );
begField = begField + 16; /* skip past label */
endField /* find end of dept. no. */
= strstr( phvRESUME," " );
strncpy( D8EMEDY1, /* get dept# from in between */
begField,
endField - begField );
begField = endField + 16; /* set loc to degree descript */
endField /* find end of deg descr data */
= strstr( phvRESUME," " );
strncpy( D8EMEDD1, /* get deg descr from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get institution that granted employee's most recent degree *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to inst name data */
phvRESUME = begField; /* point to beginning */
endField /* find end of inst name data */
= strstr( phvRESUME," " );
strncpy( D8EMEDI1, /* get inst name from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get year and description of employee's previous degree *
*******************************************************************/
if( status == OK )
{
begField = endField + 3; /* set loc to grad year data */
endField /* find end of grad year data */
= strstr( phvRESUME," " );
strncpy( D8EMEDY2, /* get hire data from in betw */
begField,
endField - begField );
begField = endField + 16; /* set loc to degree descript */
endField /* find end of deg descr data */
= strstr( phvRESUME," " );
strncpy( D8EMEDD2, /* get deg descr from in betw */
begField,
endField - begField );
}
/*******************************************************************
* Get institution that granted employee's previous degree *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to inst name data */
phvRESUME = begField; /* reset starting point */
strcpy( D8EMEDI2, /* inst name is at end of str */
begField );
}
} /* end getEducationData */
void getWorkHistoryData( void )
/*********************************************************************
* Called by the formatEmplResume routine to parse the CLOB locator *
* data for the employee's job dates, titles, and descriptions into *
* ISPF variables. *
*********************************************************************/
{
/*******************************************************************
* Extract the Work History Data section from the CLOB locator *
*******************************************************************/
begSection = endSection; /* Locate start of Work Hist */
EXEC SQL SET :endSection /* Locate start of Interests */
= POSSTR( :clRESUME, ' Interests ' );
if( SQLCODE != 0 )
{
status = NOT_OK;
sql_error( "getWorkHistoryData @ POSSTR" );
}
if( status == OK )
{
EXEC SQL SET :hvRESUME /* extract what's in between */
= SUBSTR( :clRESUME, :begSection, :endSection-:begSection );
if( SQLCODE == 0 )
hvRESUME.data[hvRESUME.length] = '\0';
else
{
status = NOT_OK;
sql_error( "getWorkHistoryData @ SUBSTR" );
}
}
/*******************************************************************
* Get dates and title of employee's most recent job *
*******************************************************************/
if( status == OK )
{
phvRESUME = &hvRESUME.data[0]; /* set pointer to the data */
begField /* find Work History label */
= strstr( phvRESUME," Work History " );
begField = begField + 19; /* set loc to job 1 dates */
phvRESUME = begField; /* reset starting point */
strncpy( D8EMWHD1, /* job 1 dates, next 15 bytes */
begField,
15 );
begField = begField + 20; /* set loc to job 1 title */
endField /* find end of job 1 title */
= strstr( phvRESUME," " );
strncpy( D8EMWHT1, /* get job 1 title from betw */
begField,
endField - begField );
}
/*******************************************************************
* Get description of employee's most recent job *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to job 1 descr. */
phvRESUME = begField; /* reset starting point */
endField /* find end of job 1 descr. */
= strstr( phvRESUME,". " );
if( endField - begField < 62 ) /* job 1 descr has 1 part */
strncpy( D8EMWHJ1, /* get job 1 descr from betw */
begField,
endField - begField );
else /* job 1 descr has 2 parts */
{
endField /* find 1st part of job descr */
= strstr( phvRESUME," " );
strncpy( D8EMWHJ1, /* get job 1 descr from betw */
begField,
endField - begField );
begField = endField + 22; /* set loc to 2nd part job des*/
endField /* find end of job 1 descr. */
= strstr( phvRESUME,". " );
strncat( D8EMWHJ1, /* get rest of job 1 descr. */
begField-1,
endField - (begField-1) );
}
}
/*******************************************************************
* Get dates and title of employee's previous job *
*******************************************************************/
if( status == OK )
{
begField = endField + 4; /* set loc to job 2 dates */
phvRESUME = begField; /* reset starting point */
strncpy( D8EMWHD2, /* job 2 dates, next 15 bytes */
begField,
15 );
begField = begField + 20; /* set loc to job 2 title */
endField /* find end of job 2 title */
= strstr( phvRESUME," " );
strncpy( D8EMWHT2, /* get job 2 title from betw */
begField,
endField - begField );
}
/*******************************************************************
* Get description of employee's previous job *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to job 2 descr. */
phvRESUME = begField; /* reset starting point */
endField /* find end of job 2 descr. */
= strstr( phvRESUME,". " );
if( endField - begField < 62 ) /* job 2 descr has 1 part */
strncpy( D8EMWHJ2, /* get job 2 title from betw */
begField,
endField - begField );
else /* job 2 descr has 2 parts */
{
endField /* find 1st part of job descr */
= strstr( phvRESUME," " );
strncpy( D8EMWHJ2, /* get job 2 descr from betw */
begField,
endField - begField );
begField = endField + 22; /* set loc to 2nd part job des*/
endField /* find end of job 2 descr. */
= strstr( phvRESUME,". " );
strncat( D8EMWHJ2, /* get rest of job 2 descr. */
begField-1,
endField - (begField-1) );
}
}
/*******************************************************************
* Get dates and title of employee's other previous job *
*******************************************************************/
if( status == OK )
{
begField = endField + 4; /* set loc to job 3 dates */
phvRESUME = begField; /* reset starting point */
strncpy( D8EMWHD3, /* job 3 dates, next 15 bytes */
begField,
15 );
begField = begField + 20; /* set loc to job 3 title */
endField /* find end of job 3 title */
= strstr( phvRESUME," " );
strncpy( D8EMWHT3, /* get job 3 title from betw */
begField,
endField - begField );
}
/*******************************************************************
* Get description of employee's other previous job *
*******************************************************************/
if( status == OK )
{
begField = endField + 22; /* set loc to job 3 descr. */
phvRESUME = begField; /* reset starting point */
begField = phvRESUME; /* reset starting point */
endField /* find end of job 3 descr. */
= strstr( phvRESUME,"." );
if( endField - begField < 62 ) /* job 3 descr has 1 part */
strncpy( D8EMWHJ3, /* get job 3 title from betw */
begField,
endField - begField );
else /* job 3 descr has 2 parts */
{
endField /* find 1st part of job descr */
= strstr( phvRESUME," " );
strncpy( D8EMWHJ3, /* get job 3 descr from betw */
begField,
endField - begField );
begField = endField + 22; /* set loc to 2nd part job des*/
endField /* find end of job 3 descr. */
= strstr( phvRESUME,". " );
strncat( D8EMWHJ3, /* get rest of job 3 descr. */
begField-1,
endField - (begField-1) );
}
}
} /* end getWorkHistoryData */
void showEmplResume( void )
/*********************************************************************
* Called by the main routine. Displays an ISPF panel that is for- *
* matted with the resume data for the employee specified. *
*********************************************************************/
{
ISPFrc = isplink( "DISPLAY ","DSN8SSR " );
} /* end showEmplResume */
void freeISPFvars( void )
/*********************************************************************
* Called by the main routine. Frees the ISPF variables that were *
* established for running this application. *
*********************************************************************/
{
ISPFrc = isplink( VRESET );
} /* end freeISPFvars */
void sql_error( char *locmsg )
/*********************************************************************
* SQL error handler *
*********************************************************************/
{
short int rc; /* DSNTIAR Return code */
int j,k; /* Loop control */
static int lrecl = TIAR_LEN; /* Width of message lines */
/*******************************************************************
* print the location message *
*******************************************************************/
printf( "*****************************************************\n" );
printf( "*** ERROR: DSN8DLRV DB2 Sample Program\n" );
printf( "*** Unexpected SQLCODE encountered at location\n" );
printf( "*** %.68s\n", locmsg );
printf( "*** Error detailed below\n" );
printf( "*** Processing terminated\n" );
printf( "*****************************************************\n" );
/*******************************************************************
* format and print the SQL message *
*******************************************************************/
rc = dsntiar( &sqlca, &error_message, &lrecl );
if( rc == 0 )
for( j=0; j<TIAR_DIM; j++ )
{
for( k=0; k<TIAR_LEN; k++ )
putchar(error_message.error_text[j][k] );
putchar('\n');
}
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
} /* end sql_error */