DSN8DUWF
Returns weather information for various cities, as read from the data set passed as the argument to input para- meter 'weatherDSN'.
/********************************************************************* 00000100
* Module name = DSN8DUWF (DB2 sample program) * 00000200
* * 00000300
* DESCRIPTIVE NAME = Weather (DB2 user-defined table function) * 00000400
* * 00000500
* 5675-DB2 * 00000600
* (C) COPYRIGHT 1998, 2000 IBM CORP. * 00000700
* * 00000800
* STATUS = VERSION 7 * 00000900
* * 00001000
* Function: Returns weather information for various cities, as read * 00001100
* from the data set passed as the argument to input para- * 00001200
* meter 'weatherDSN'. The data includes the name of a * 00001300
* city followed by its weather information: Temperature in * 00001400
* fahrenheit, percent humidity, wind direction, wind velo- * 00001500
* city, barometric pressure, and the forecast. See the * 00001600
* structure 'weatherRec' for the record format. * 00001700
* * 00001800
* File pointer information is retained between calls in * 00001900
* the UDF scratchpad area. * 00002000
* * 00002100
* Data read from the input data set is returned by this * 00002200
* function as a DB2 table with the following structure: * 00002300
* with this structure: * 00002400
* * 00002500
* CITY VARCHAR(30), * 00002600
* TEMP_IN_F INTEGER, * 00002700
* HUMIDITY INTEGER, * 00002800
* WIND VARCHAR(5), * 00002900
* WIND_VELOCITY INTEGER, * 00003000
* BAROMETER FLOAT, * 00003100
* FORECAST VARCHAR(25) * 00003200
* * 00003300
* Clients invoking this function can use standard SQL * 00003400
* syntax to create a desired result set. * 00003500
* * 00003600
* Example invocation: * 00003700
* * 00003800
* EXEC SQL DECLARE WEATHER_CURSOR * 00003900
* CURSOR FOR * 00004000
* SELECT CITY, * 00004100
* FORECAST * 00004200
* FROM TABLE( DSN8.WEATHER(:hvWeatherDSN) ) * 00004300
* AS W * 00004400
* WHERE CITY = 'Juneau, AK'; * 00004500
* * 00004600
* Notes: * 00004700
* Dependencies: Requires IBM C/C++ for OS/390 V1R3 or higher * 00004800
* * 00004900
* Restrictions: * 00005000
* * 00005100
* Module type: C program * 00005200
* Processor: IBM C/C++ for OS/390 V1R3 or higher * 00005300
* Module size: See linkedit output * 00005400
* Attributes: Re-entrant and re-usable * 00005500
* * 00005600
* Entry Point: DSN8DUWF * 00005700
* Purpose: See Function * 00005800
* Linkage: DB2SQL * 00005900
* Invoked via SQL UDF call * 00006000
* * 00006100
* * 00006200
* Input: Parameters explicitly passed to this function: * 00006300
* - *weatherDSN : pointer to a char[45], null-termi- * 00006400
* nated string having the name of the * 00006500
* source data for the weather reports. * 00006600
* - *niWeatherDSN: pointer to a short integer having * 00006700
* the null indicator variable for * 00006800
* *weatherDSN. * 00006900
* - *fnName : pointer to a char[138], null-termi- * 00007000
* nated string having the UDF family * 00007100
* name of this function. * 00007200
* - *specificName: pointer to a char[129], null-termi- * 00007300
* nated string having the UDF specific * 00007400
* name of this function. * 00007500
* * 00007600
* * 00007700
* Output: Parameters explicitly passed by this function: * 00007800
* - *city : pointer to a char[31], null-termi- * 00007900
* nated string to receive the name of * 00008000
* the city. * 00008100
* - *temp_in_f : pointer to a long integer to receive * 00008200
* the temperature in fahrenheit for * 00008300
* the city. * 00008400
* - *humidity : pointer to a long integer to receive * 00008500
* the percent humidity for the city. * 00008600
* - *wind : pointer to a char[6], null-termi- * 00008700
* nated string to receive the wind di- * 00008800
* rection for the city. * 00008900
* - *wind_velocity: pointer to a long integer to receive* 00009000
* the wind velocity for city. * 00009100
* - *barometer : pointer to a double word to receive * 00009200
* the barometric pressure for the city.* 00009300
* - *forecast : pointer to a char[26], null-termi- * 00009400
* nated string to receive the forecast * 00009500
* for the city. * 00009600
* - *niCity : pointer to a short integer to re- * 00009700
* ceive the null indicator variable * 00009800
* for *city. * 00009900
* - *niTemp_in_f : pointer to a short integer to re- * 00010000
* ceive the null indicator variable * 00010100
* for *temp_in_f. * 00010200
* - *niHumidity : pointer to a short integer to re- * 00010300
* ceive the null indicator variable * 00010400
* for *humidity. * 00010500
* - *niWind : pointer to a short integer to re- * 00010600
* ceive the null indicator variable * 00010700
* for *wind. * 00010800
* - *niWind_velocity: pointer to a short integer to re- * 00010900
* ceive the null indicator variable * 00011000
* for *wind_velocity. * 00011100
* - *niBarometer : pointer to a short integer to re- * 00011200
* ceive the null indicator variable * 00011300
* for *barometer. * 00011400
* - *niForecast : pointer to a short integer to re- * 00011500
* ceive the null indicator variable * 00011600
* for *forecast. * 00011700
* - *sqlstate : pointer to a char[06], null-termi- * 00011800
* nated string to receive the SQLSTATE.* 00011900
* - *message : pointer to a char[70], null-termi- * 00012000
* nated string to receive a diagnostic * 00012100
* message if one is generated by this * 00012200
* function. * 00012300
* * 00012400
* Normal Exit: Return Code: SQLSTATE = 00000 * 00012500
* - Message: none * 00012600
* * 00012700
* Return Code: SQLSTATE = 02000 (end of input) * 00012800
* - Message: none * 00012900
* * 00013000
* Error Exit: Return Code: SQLSTATE = 38601 * 00013100
* - Message: DSN8DUWF Error: Unable to allocate DD * 00013200
* <ddname>: Error code=<x>, * 00013300
* info code=<y> * 00013400
* * 00013500
* Return Code: SQLSTATE = 38602 * 00013600
* - Message: DSN8DUWF Error: Error opening weather data * 00013700
* set * 00013800
* * 00013900
* Return Code: SQLSTATE = 38603 * 00014000
* - Message: DSN8DUWF Error: Error reading weather data * 00014100
* set * 00014200
* * 00014300
* Return Code: SQLSTATE = 38604 * 00014400
* - Message: DSN8DUWF Error: Error closing weather data * 00014500
* set * 00014600
* * 00014700
* Return Code: SQLSTATE = 38605 * 00014800
* - Message: DSN8DUWF Error: FREE failed for DDNAME <x>.* 00014900
* Error code=<y>, info code= * 00015000
* <z> * 00015100
* * 00015200
* External References: * 00015300
* - Routines/Services: dyninit: IBM C/C++, dynit.h * 00015400
* - Initializes control block for * 00015500
* dynamic file allocation * 00015600
* dynalloc: IBM C/C++, dynit.h * 00015700
* - Dynamic file allocation * 00015800
* dynfree: IBM C/C++, dynit.h * 00015900
* - Dynamic file deallocation * 00016000
* - Data areas : None * 00016100
* - Control blocks : __dyn_t: IBM C/C++, dynint.h * 00016200
* - for dynamic file allocation * 00016300
* * 00016400
* Pseudocode: * 00016500
* DSN8DUWF: * 00016600
* - If SQLUDF call type is SQLUDF_TF_FIRST (-2) * 00016700
* - call allocWeatherDSN to allocate the data set name passed as * 00016800
* the argument to the weatherDSN parameter * 00016900
* - Else if SQLUDF call type is SQLUDF_TF_OPEN (-1) * 00017000
* - call openWeatherDS to open the weather data set * 00017100
* - Else if SQLUDF call type is SQLUDF_TF_FETCH (0) * 00017200
* - call readWeatherDS to read the next record from the weather * 00017300
* data set * 00017400
* - if EOF, set sqlstate to 02000 to signal end of cursor to * 00017500
* client * 00017600
* - else call buildReturnRow to populate the UDF table function * 00017700
* output parameters with data from the input record * 00017800
* - Else if SQLUDF call type is SQLUDF_TF_CLOSE (1) * 00017900
* - call closeWeatherDS to close the weather data set * 00018000
* - Else (SQLUDF call type is SQLUDF_TF_FINAL (2) ) * 00018100
* - call freeWeatherDS to deallocate the weather data set * 00018200
* End DSN8DUWF * 00018300
* * 00018400
* allocWeatherDS: * 00018500
* - if the data set name passed in as the argument to the input * 00018600
* parameter weatherDSN is for a partitioned data set, extract * 00018700
* the member name * 00018800
* - use dynalloc to dynamically allocate the data set (and member, * 00018900
* if applicable) * 00019000
* - if allocation error occurs, issue sqlstate 38601 and a diag- * 00019100
* nostic message * 00019200
* End allocWeatherDS * 00019300
* * 00019400
* openWeatherDS: * 00019500
* - open the weather data set * 00019600
* - if the data cannot be opened, issue sqlstate 38602 and a diag- * 00019700
* nostic message * 00019800
* End openWeatherDS * 00019900
* * 00020000
* readWeatherDS: * 00020100
* - read the next record from the data set * 00020200
* - this implicitly updates the file pointer variable, which is * 00020300
* maintained in the UDF scratchpad area * 00020400
* - if the data set cannot be read, issue sqlstate 38603 and a * 00020500
* diagnostic message * 00020600
* End readWeatherDS * 00020700
* * 00020800
* buildReturnRow: * 00020900
* - extract weather data fields from the weather data set * 00021000
* - perform appropriate data type conversions * 00021100
* - copy the (converted) data to the appropriate output parameters * 00021200
* End buildReturnRow * 00021300
* * 00021400
* closeWeatherDS: * 00021500
* - close the weather data set * 00021600
* - if the data cannot be closed, issue sqlstate 38604 and a diag- * 00021700
* nostic message * 00021800
* End closeWeatherDS * 00021900
* * 00022000
* freeWeatherDS: * 00022100
* - use dynfree to dynamically deallocate the weather data set * 00022200
* - if deallocation error occurs, issue sqlstate 38605 and a diag- * 00022300
* nostic message * 00022400
* End freeWeatherDS * 00022500
* * 00022600
*********************************************************************/ 00022700
00022800
#pragma linkage(DSN8DUWF,fetchable) 00022900
00023000
/********************** C library definitions ***********************/ 00023100
#include <dynit.h> 00023200
#include <stdlib.h> 00023300
#include <string.h> 00023400
#include <stdio.h> 00023500
00023600
/***************************** Equates ******************************/ 00023700
#define NO 0 /* Negative */ 00023800
#define YES 1 /* Affirmative */ 00023900
00024000
#define NULLCHAR '\0' /* Null character */ 00024100
00024200
#define SQLUDF_TF_FIRST -2 /* First call */ 00024300
#define SQLUDF_TF_OPEN -1 /* Open table call */ 00024400
#define SQLUDF_TF_FETCH 0 /* Fetch next row call */ 00024500
#define SQLUDF_TF_CLOSE 1 /* Close table call */ 00024600
#define SQLUDF_TF_FINAL 2 /* Final call */ 00024700
00024800
/************************ Weather Data Set **************************/ 00024900
struct scr /* Struct for scratchpad area */ 00025000
{ 00025100
long len; /* Length of scratchpad data */ 00025200
FILE *WEATHRin; /* ptr to weather data set */ 00025300
char not_used[100]; /* filler */ 00025400
}; 00025500
00025600
char WEATHRinBuffer[8188]; /* Input buffer for weather ds*/ 00025700
short int moreWeatherRecs = YES;/* EOF indicator, weather ds */ 00025800
00025900
typedef struct /* Weather record structure */ 00026000
{ 00026100
char cityField[30]; /* name of city 01-30 */ 00026200
char filler1[1]; /* 31-31 */ 00026300
char temp_in_fField[3]; /* temp in fahrenheit 32-34 */ 00026400
char filler2[1]; /* 35-35 */ 00026500
char humidityField[3]; /* percent humidity 36-38 */ 00026600
char filler3[1]; /* 39-39 */ 00026700
char windField[5]; /* wind direction 40-44 */ 00026800
char filler4[1]; /* 45-45 */ 00026900
char windVelocityField[3]; /* wind velocity 46-48 */ 00027000
char filler5[1]; /* 49-49 */ 00027100
char barometerField[5]; /* baromtric pressure 50-54 */ 00027200
char filler6[1]; /* 55-55 */ 00027300
char forecastField[25]; /* forecast 56-80 */ 00027400
} weatherRec; 00027500
00027600
weatherRec *pweatherRec = (weatherRec *)&WEATHRinBuffer; 00027700
00027800
00027900
/*************************** Functions ******************************/ 00028000
void *DSN8DUWF /* Weather function */ 00028100
( char *weatherDSN, /* in: input ds, weather data */ 00028200
char *city, /* out: name of city */ 00028300
long int *temp_in_f, /* out: temp in fahrenheit */ 00028400
long int *humidity, /* out: relative humidity */ 00028500
char *wind, /* out: wind direction */ 00028600
long int *wind_velocity, /* out: wind velocity */ 00028700
double *barometer, /* out: barometric pressure */ 00028800
char *forecast, /* out: forecast */ 00028900
short int *niWeatherDSN, /* in: indic var, weather dsn */ 00029000
short int *niCity, /* out: indic var, city name */ 00029100
short int *niTemp_in_f, /* out: indic var, temperature*/ 00029200
short int *niHumidity, /* out: indic var, humidity */ 00029300
short int *niWind, /* out: indic var, wind dir */ 00029400
short int *niWind_velocity, /* out: indic var, wind veloc */ 00029500
short int *niBarometer, /* out: indic var, baro press */ 00029600
short int *niForecast, /* out: indic var, forecast */ 00029700
char *sqlstate, /* out: SQLSTATE */ 00029800
char *fnName, /* in: family name of function*/ 00029900
char *specificName, /* in: specific name of func */ 00030000
char *msgtext, /* out: diagnostic message */ 00030100
struct scr *scratchptr, /* i/o: scratchpad area */ 00030200
long *callType /* i/o: call type parameter */ 00030300
); 00030400
00030500
void allocWeatherDS /* Dynam allocates weather ds */ 00030600
( char *weatherDSN, /* in: name of weather ds */ 00030700
char *sqlstate, /* out: sqlstate */ 00030800
char *msgtext /* out: diag message text */ 00030900
); 00031000
00031100
void openWeatherDS /* Opens weather data set */ 00031200
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00031300
char *sqlstate, /* out: sqlstate */ 00031400
char *msgtext /* out: diag message text */ 00031500
); 00031600
00031700
void readWeatherDS /* Reads from weather data set*/ 00031800
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00031900
char *sqlstate, /* out: sqlstate */ 00032000
char *msgtext /* out: diag message text */ 00032100
); 00032200
00032300
void buildReturnRow /* Builds function return row */ 00032400
( char *city, /* out: name of city */ 00032500
long int *temp_in_f, /* out: temp in fahrenheit */ 00032600
long int *humidity, /* out: relative humidity */ 00032700
char *wind, /* out: wind direction */ 00032800
long int *wind_velocity, /* out: wind velocity */ 00032900
double *barometer, /* out: barometric pressure */ 00033000
char *forecast, /* out: forecast */ 00033100
short int *niCity, /* out: indic var, city name */ 00033200
short int *niTemp_in_f, /* out: indic var, temperature*/ 00033300
short int *niHumidity, /* out: indic var, humidity */ 00033400
short int *niWind, /* out: indic var, wind dir */ 00033500
short int *niWind_velocity, /* out: indic var, wind veloc */ 00033600
short int *niBarometer, /* out: indic var, baro press */ 00033700
short int *niForecast /* out: indic var, forecast */ 00033800
); 00033900
00034000
void closeWeatherDS /* Closes weather data set */ 00034100
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00034200
char *sqlstate, /* out: sqlstate */ 00034300
char *msgtext /* out: diag message text */ 00034400
); 00034500
00034600
void freeWeatherDS /* Dynam frees the weather ds */ 00034700
( char *sqlstate, /* out: sqlstate */ 00034800
char *msgtext /* out: diag message text */ 00034900
); 00035000
00035100
00035200
void *DSN8DUWF 00035300
( char *weatherDSN, /* in: input ds, weather data */ 00035400
char *city, /* out: name of city */ 00035500
long int *temp_in_f, /* out: temp in fahrenheit */ 00035600
long int *humidity, /* out: relative humidity */ 00035700
char *wind, /* out: wind direction */ 00035800
long int *wind_velocity, /* out: wind velocity */ 00035900
double *barometer, /* out: barometric pressure */ 00036000
char *forecast, /* out: forecast */ 00036100
short int *niWeatherDSN, /* in: indic var, weather dsn */ 00036200
short int *niCity, /* out: indic var, city name */ 00036300
short int *niTemp_in_f, /* out: indic var, temperature*/ 00036400
short int *niHumidity, /* out: indic var, humidity */ 00036500
short int *niWind, /* out: indic var, wind dir */ 00036600
short int *niWind_velocity, /* out: indic var, wind veloc */ 00036700
short int *niBarometer, /* out: indic var, baro press */ 00036800
short int *niForecast, /* out: indic var, forecast */ 00036900
char *sqlstate, /* out: SQLSTATE */ 00037000
char *fnName, /* in: family name of function*/ 00037100
char *specificName, /* in: specific name of func */ 00037200
char *msgtext, /* out: diagnostic message */ 00037300
struct scr *scratchptr, /* i/o: scratchpad area */ 00037400
long *callType /* i/o: call type parameter */ 00037500
) 00037600
/********************************************************************* 00037700
* Main routine for Weather table function * 00037800
*********************************************************************/ 00037900
{ 00038000
/******************************************************************* 00038100
* First call: Dynamically allocate the weather data set * 00038200
*******************************************************************/ 00038300
if( *callType == SQLUDF_TF_FIRST ) 00038400
{ 00038500
strcpy( sqlstate,"00000" ); /* Init sqlstate return var */ 00038600
*msgtext = NULLCHAR; /* Init message text rtrn var */ 00038700
allocWeatherDS( weatherDSN, sqlstate, msgtext ); 00038800
} 00038900
/******************************************************************* 00039000
* Second call: Open the weather data set * 00039100
*******************************************************************/ 00039200
else if( *callType == SQLUDF_TF_OPEN ) 00039300
{ 00039400
strcpy( sqlstate,"00000" ); /* Init sqlstate return var */ 00039500
*msgtext = NULLCHAR; /* Init message text rtrn var */ 00039600
moreWeatherRecs = YES; /* EOF indicator, weather ds */ 00039700
openWeatherDS( scratchptr, sqlstate, msgtext ); 00039800
} 00039900
/******************************************************************* 00040000
* Subsequent calls: Read a record from the weather data set * 00040100
*******************************************************************/ 00040200
else if( *callType == SQLUDF_TF_FETCH ) 00040300
{ 00040400
readWeatherDS( scratchptr, sqlstate, msgtext ); 00040500
if( moreWeatherRecs == NO ) /* If no more weather data */ 00040600
strcpy( sqlstate,"02000" ); /* ..signal for FINAL CALL */ 00040700
else 00040800
{ 00040900
buildReturnRow( city, 00041000
temp_in_f, 00041100
humidity, 00041200
wind, 00041300
wind_velocity, 00041400
barometer, 00041500
forecast, 00041600
niCity, 00041700
niTemp_in_f, 00041800
niHumidity, 00041900
niWind, 00042000
niWind_velocity, 00042100
niBarometer, 00042200
niForecast ); 00042300
} 00042400
} 00042500
/******************************************************************* 00042600
* End of file: Close weather data set * 00042700
*******************************************************************/ 00042800
else if( *callType == SQLUDF_TF_CLOSE ) 00042900
{ 00043000
closeWeatherDS( scratchptr, sqlstate, msgtext ); 00043100
} 00043200
/******************************************************************* 00043300
* Final call: De-allocate weather data set * 00043400
*******************************************************************/ 00043500
else /* *callType == SQLUDF_TF_FINAL */ 00043600
{ 00043700
freeWeatherDS( sqlstate, msgtext ); 00043800
} 00043900
return; 00044000
} 00044100
00044200
00044300
void allocWeatherDS 00044400
( char *weatherDSN, /* in: name of weather ds */ 00044500
char *sqlstate, /* out: sqlstate */ 00044600
char *msgtext /* out: diag message text */ 00044700
) 00044800
/********************************************************************* 00044900
* Dynamically allocates weatherDSN to the WEATHRIN DD. If the value * 00045000
* in weatherDSN contains parentheses, it is assumed to specify a * 00045100
* partitioned data set; otherwise it is assumed to specify a * 00045200
* physical sequential data set. * 00045300
*********************************************************************/ 00045400
{ 00045500
__dyn_t ip; /* pointer to control block */ 00045600
char DSname[45]; /* recv's copy of weather dsn */ 00045700
char *tokPtr; /* string ptr for token parser*/ 00045800
00045900
dyninit( &ip ); /* Initialize control block */ 00046000
ip.__ddname = "WEATHRIN"; /* Specify DDNAME of WEATHRIN */ 00046100
/******************************************************************* 00046200
* Use the strtok func to separate the PDS member name, if any, * 00046300
* from the data set name * 00046400
*******************************************************************/ 00046500
strcpy( DSname,weatherDSN ); /* Get workcopy of weather dsn*/ 00046600
tokPtr = strtok( DSname,"(" ); /* Parse for open parenthesis */ 00046700
if( tokPtr == NULL ) /* If none found then */ 00046800
ip.__dsname = DSname; /* ...data set is not a PDS */ 00046900
else /* Otherwise */ 00047000
{ 00047100
ip.__dsname = tokPtr; /* ...token is name of a PDS */ 00047200
tokPtr = strtok( NULL,")" ); /* ...parse for close paren */ 00047300
ip.__member = tokPtr; /* ...token is name of member */ 00047400
} 00047500
ip.__status = __DISP_SHR; /* Specify DISP=SHR */ 00047600
00047700
/******************************************************************* 00047800
* If dynamic allocation failed, generate an error message and quit * 00047900
*******************************************************************/ 00048000
if( dynalloc(&ip) != 0 ) 00048100
{ 00048200
sprintf( msgtext,"Unable to allocate DD %s: " 00048300
"Error code=%hX, info code=%hX\n", 00048400
ip.__ddname, 00048500
ip.__errcode, 00048600
ip.__infocode ); 00048700
strcpy( sqlstate,"38601" ); 00048800
} 00048900
} /* end allocWeatherDS */ 00049000
00049100
00049200
void openWeatherDS 00049300
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00049400
char *sqlstate, /* out: sqlstate */ 00049500
char *msgtext /* out: diag message text */ 00049600
) 00049700
/********************************************************************* 00049800
* Opens the weather data set, which has been allocated to the DD * 00049900
* WEATHRIN, for record-type input, and assigns the file pointer to * 00050000
* the scratchpad area indicated by scratchptr. * 00050100
*********************************************************************/ 00050200
{ 00050300
scratchptr->WEATHRin = fopen("DD:WEATHRIN", 00050400
"rb,recfm=vb,lrecl=8188,type=record"); 00050500
00050600
if( scratchptr->WEATHRin == NULL ) /* If unable to open data set */ 00050700
{ /* ..set return msg and state */ 00050800
strcpy( msgtext,"Error opening weather data set" ); 00050900
strcpy( sqlstate,"38602" ); 00051000
} 00051100
} /* end openWeatherDS */ 00051200
00051300
00051400
void readWeatherDS 00051500
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00051600
char *sqlstate, /* out: sqlstate */ 00051700
char *msgtext /* out: diag message text */ 00051800
) 00051900
/********************************************************************* 00052000
* Reads the next record from the weather data set * 00052100
*********************************************************************/ 00052200
{ 00052300
short int recordLength = 0; /* Receives len of current rec*/ 00052400
00052500
recordLength /* */ 00052600
= fread( WEATHRinBuffer, /* Read into WEATHRinBuffer */ 00052700
1, /* ..a record */ 00052800
sizeof( WEATHRinBuffer ),/* ..<= len of WEATHRinBuffer */ 00052900
scratchptr->WEATHRin ); /* ..from the weather data set*/ 00053000
00053100
if( ferror(scratchptr->WEATHRin) ) /* If an error occurs */ 00053200
{ /* ..set return msg and state */ 00053300
strcpy( msgtext,"Error reading weather data set" ); 00053400
strcpy( sqlstate,"38603" ); 00053500
} 00053600
else if( feof(scratchptr->WEATHRin))/* Else if end of file reached*/ 00053700
moreWeatherRecs = NO; /* ..get ready to quit */ 00053800
} /* end readWeatherDS */ 00053900
00054000
00054100
void buildReturnRow /* Builds function return row */ 00054200
( char *city, /* out: name of city */ 00054300
long int *temp_in_f, /* out: temp in fahrenheit */ 00054400
long int *humidity, /* out: relative humidity */ 00054500
char *wind, /* out: wind direction */ 00054600
long int *wind_velocity, /* out: wind velocity */ 00054700
double *barometer, /* out: barometric pressure */ 00054800
char *forecast, /* out: forecast */ 00054900
short int *niCity, /* out: indic var, city name */ 00055000
short int *niTemp_in_f, /* out: indic var, temperature*/ 00055100
short int *niHumidity, /* out: indic var, humidity */ 00055200
short int *niWind, /* out: indic var, wind dir */ 00055300
short int *niWind_velocity, /* out: indic var, wind veloc */ 00055400
short int *niBarometer, /* out: indic var, baro press */ 00055500
short int *niForecast /* out: indic var, forecast */ 00055600
) 00055700
/********************************************************************* 00055800
* Build a return row for the current call to the WEATHER table * 00055900
* function. * 00056000
*********************************************************************/ 00056100
{ 00056200
char workBuff[6]; /* for datatype conversions */ 00056300
00056400
/******************************************************************* 00056500
* Move the city name to its table variable * 00056600
*******************************************************************/ 00056700
strncpy( city,pweatherRec->cityField,30 ); 00056800
*niCity = 0; 00056900
00057000
/******************************************************************* 00057100
* Move the temperature to its table var after making it numeric * 00057200
*******************************************************************/ 00057300
memset( workBuff,'\0',6 ); 00057400
strncpy( workBuff,pweatherRec->temp_in_fField,3 ); 00057500
*temp_in_f = atoi( workBuff ); 00057600
*niTemp_in_f = 0; 00057700
00057800
/******************************************************************* 00057900
* Move the humidity factor to its table var after making it numeric* 00058000
*******************************************************************/ 00058100
memset( workBuff,'\0',6 ); 00058200
strncpy( workBuff,pweatherRec->humidityField,3 ); 00058300
*humidity = atoi( workBuff ); 00058400
*niHumidity = 0; 00058500
00058600
/******************************************************************* 00058700
* Move the wind direction to its table variable * 00058800
*******************************************************************/ 00058900
strncpy( wind,pweatherRec->windField,5 ); 00059000
*niWind = 0; 00059100
00059200
/******************************************************************* 00059300
* Move the wind velocity to its table var after making it numeric * 00059400
*******************************************************************/ 00059500
memset( workBuff,'\0',6 ); 00059600
strncpy( workBuff,pweatherRec->windVelocityField,3 ); 00059700
*wind_velocity = atoi( workBuff ); 00059800
*niWind_velocity = 0; 00059900
00060000
/******************************************************************* 00060100
* Move the forecast to its table variable * 00060200
*******************************************************************/ 00060300
memset( workBuff,'\0',6 ); 00060400
strncpy( workBuff,pweatherRec->barometerField,5 ); 00060500
*barometer = atof( workBuff ); 00060600
*niBarometer = 0; 00060700
00060800
/******************************************************************* 00060900
* Move the forecast to its table variable * 00061000
*******************************************************************/ 00061100
strncpy( forecast,pweatherRec->forecastField,25 ); 00061200
*niForecast = 0; 00061300
00061400
} /* end buildReturnRow */ 00061500
00061600
00061700
void closeWeatherDS 00061800
( struct scr *scratchptr, /* in: ptr to scratch pad */ 00061900
char *sqlstate, /* out: sqlstate */ 00062000
char *msgtext /* out: diag message text */ 00062100
) 00062200
/********************************************************************* 00062300
* Closes the weather data set and resets the file pointer in the * 00062400
* scratchpad area. * 00062500
*********************************************************************/ 00062600
{ 00062700
if( fclose(scratchptr->WEATHRin) != 0 ) 00062800
/* If unable to close data set*/ 00062900
{ /* ..set return msg and state */ 00063000
strcpy( msgtext,"Error closing weather data set" ); 00063100
strcpy( sqlstate,"38604" ); 00063200
} 00063300
else 00063400
scratchptr->WEATHRin = NULLCHAR; /* Otherwise, reset file ptr */ 00063500
} /* end closeWeatherDS */ 00063600
00063700
00063800
void freeWeatherDS 00063900
( char *sqlstate, /* out: sqlstate */ 00064000
char *msgtext /* out: diag message text */ 00064100
) 00064200
/********************************************************************* 00064300
* Dynamically frees the weather data set, which has been allocated * 00064400
* to the WEATHRIN DD. * 00064500
*********************************************************************/ 00064600
{ 00064700
__dyn_t free_ip; /* pointer to control block */ 00064800
00064900
dyninit( &free_ip ); /* Initialize control block */ 00065000
free_ip.__ddname = "WEATHRIN"; /* Set DD name of weather ds */ 00065100
00065200
if( dynfree(&free_ip) != 0 ) 00065300
{ 00065400
sprintf( msgtext,"FREE failed for DDNAME %s. " 00065500
"Error code=%hX, info code=%hX\n", 00065600
free_ip.__errcode, 00065700
free_ip.__errcode, 00065800
free_ip.__infocode ); 00065900
strcpy( sqlstate,"38605" ); 00066000
} 00066100
} /* end freeWeatherDS */ 00066200