INFORMIX
Informix-ESQL/C Programmer's Manual
Chapter 8: Working with Simple Large Objects
Home Contents Index Master Index New Book

The dispcat_pic Program

The dispcat_pic demo program is only implemented on UNIX platforms.

The dispcat_pic program, annotated on the following pages, uses the ESQL/C loc_t locator structure to retrieve two simple-large-object columns. The program retrieves the cat_descr TEXT simple-large-object column and the cat_picture BYTE column from the catalog table of the stores7 demonstration database. For information on how to create the demonstration database, see "Demonstration Database" in the Introduction.

The dispcat_pic program allows you to select a database from the command line in case you created the stores7 database under a different name. If no database name is given, dispcat_pic opens the stores7 database. For example, the following command runs the dispcat_pic executable and specifies the mystores database:

The program prompts the user for a catalog_num value and performs a SELECT statement to read the description column from the stock table and the catalog_num, cat_descr, and cat_picture columns from the catalog table. If the database server finds the catalog number and the cat_picture column is not null, it writes the cat_picture column to a temporary file.

If you compile the program with the -DSUNVIEW option, the program forks a second process and executes the Sun screenload system utility to display the raster image from the temporary file. In all cases, if the SELECT statement succeeds, the program displays the catalog_num, cat_descr, and description columns. Since these columns store text, they can be displayed on any ESQL/C platform. Finally, the program deletes the temporary file it created for cat_picture and allows the user to enter another catalog_num value or terminate the program.

To prepare to run the dispcat_pic program

1. Load the simple-large-object images into the catalog table with the blobload utility.

    2. Compile the dispcat_pic.ec file into an executable program. If you display the simple large objects on a Sun workstation, you specify a command-line definition to perform conditional compilation.

Loading the Simple-Large-Object Images

When the catalog table is created as part of the stores7 demonstration database, the cat_picture column for all rows is set to null. The ESQL/C demonstration directory provides five graphic images and the blobload program to load five rows of the catalog table with graphic images that can be displayed.

To display these simple-large-object images from the dispcat_pic program, you must load the images to the catalog table.

To load the images in the catalog table

1. Choose the appropriate simple-large-object images for your graphics environment.

    2. Use the blobload utility to load the simple-large-object images into the cat_picture column of the catalog table.

Choosing the Image Files

Informix provides the five cat_picture images in two formats:

Figure 8-22
Image Files for Simple-Large-Object Demo

Image Sun Raster Image Format (.rs Files) Graphics Interchange Format (.gif Files)

Baseball glove

cn_10001.rs

cn_10001.gif

Bicycle crankset

cn_10027.rs

cn_10027.gif

Bicycle helmet

cn_10031.rs

cn_10031.gif

Golf balls

cn_10046.rs

cn_10046.gif

Running shoe

cn_10049.rs

cn_10049.gif

The numeric portion of the image filename is the catalog_num value for the row of the catalog table to which the image is to be updated. For example, cn_10027.rs should be updated to the cat_picture column of the row where 10027 is the value of catalog_num.

Important: The dispcat_pic program, as delivered, only displays Sun raster images. To display the Graphics Interchange Format, or any other format, you must modify the display_picture() function of dispcat_pic, substituting display logic for logic that can use the format of your image files. For more information, see "Compiling the dispcat_pic Program".

Using the blobload Utility

The blobload utility is an ESQL/C program that is provided as part of the ESQL/C demonstration files. It uses a command-line syntax to load a byte image into a specified table and column of a database.

To load the simple-large-object images with blobload

1. Compile the blobload.ec program with the following command:

esql -o blobload blobload.ec

    2. Enter blobload on the UNIX command line without any arguments, as follows: blobload

    3. Run the blobload program to load each image to its proper cat_picture column.

    The -u option of blobload updates a specified column with a simple-large-object image. To identify which column to update, you must also use the -f, -d, -t, -b, and -k options of blobload.

You must run the blobload program once for each image file that you want to update. For example, the following command loads the contents of the cn_10027.rs file into the cat_picture column of the row for catalog_num 10027. The catalog_num column is the key column in the catalog table.

Use the same command to update each of the four remaining image files, substituting the filename (-f option) and corresponding catalog_num value (-k option) of the image file that you want to load.

You can use the blobload program to load the .gif files to the catalog table in the same manner that you use it to load the .rs files.

Compiling the dispcat_pic Program

The dispcat_pic program is provided as part of the ESQL/C demonstration files so that you can compile and run it yourself. The program includes conditional display logic to illustrate how to display a graphic image from a BYTE type column. As provided, the program can handle the display of a BYTE column in one of the following ways:

The display_picture() function of dispcat_pic contains both sets of conditional compilations. The set that the ESQL/C preprocessor uses depends on whether the SUNVIEW definition flag has been defined.

Avoiding Display of Images

To display a simple-large-object image, the dispcat_pic program must execute the appropriate image-display utility for the graphics environment. If your applications run under some graphics environment other than a Sun workstation, dispcat_pic does not call the correct image-display utility.

Use the following command to compile the dispcat_pic program so that it does not display the BYTE images:

The -o dispcat_pic option causes the executable program to be named dispcat_pic. Without the -o option, the name of the executable program defaults to a.out. For more information on the esql command, see "Using the esql Command".

When the program is compiled without the SUNVIEW flag, the program just displays the following message when it encounters a BYTE value:

To display the cat_picture column on a Sun workstation, you can set the SUNVIEW conditional flag when you compile. (For more information, see "Displaying Sun Raster Images.") To display this BYTE image on another ESQL/C platform, you must substitute display logic that runs on that platform.

Displaying Sun Raster Images

To display the Sun raster simple-large-object images, the display_picture() function uses the Sun screenload utility program.

To compile dispcat_pic with the conditional cat_picture display logic for a Sun workstation, use the following command:

The -DSUNVIEW option causes the conditional display logic to be compiled.

Tip: For simplicity, the program is not designed to display the cat_picture raster image under SunView or any other windowing environment. If you display the cat_picture column, for best results, run the program directly from the SunOS command line, not through the window manager.

Guide to the dispcat_pic.ec File

1 /*

2 * dispcat_pic.ec *


	3	    The following program prompts the user for a catalog number and 

4 displays the cat_picture column, if it is not null, for that row of

5 the catalog table.

6 WARNING: This program displays a Sun standard raster file using the

7 screenload program provided by Sun. It will display properly only

8 on a Sun display.

9 */

10 #include <stdio.h>

11 EXEC SQL include locator;

12 #define WARNNOTIFY 1

13 #define NOWARNNOTIFY 0

14 #define BUFFSZ 256

15 extern int errno;

16 EXEC SQL BEGIN DECLARE SECTION;

17 long cat_num;

18 loc_t cat_descr;

19 loc_t cat_picture;

20 EXEC SQL END DECLARE SECTION;

21 char cpfl[18];

22 main(argc, argv)

23 int argc;

24 char *argv[];

25 {

Continued on page 8-52

Lines 10 and 11

The #include <stdio.h> statement includes the stdio.h UNIX header file from the /usr/include directory. The stdio.h file enables dispcat_pic to use the standard C I/O library. The program also includes an ESQL/C header file (line 11). The locator.h file contains the definition of the locator structure and the constants that are needed to work with this structure.

Lines 12 to 15

The WARNNOTIFY and NOWARNNOTIFY constants (lines 12 and 13) are used with the exp_chk2() exception-handling function. Calls to exp_chk2() specify one of these constants as the second argument to indicate whether or not to display SQLSTATE and SQLCODE information for warnings (WARNNOTIFY or NOWARNNOTIFY). See lines 185 to 192 for more information about the exp_chk2() function.

The program uses BUFFSZ (line 14) to specify the size of arrays that store input from the user. Line 15 defines errno, an external integer where system calls store an error number.

Lines 16 to 20

These lines define global host variables needed for the program. The cat_num variable holds the catalog_num column value of the catalog table. Lines 18 and 19 specify the locator structure as the data type for host variables that receive data for the cat_descr and cat_picture simple-large-object columns of the catalog table. The locator structure is the host variable for a simple-large-object column that is retrieved from or stored to the database. The locator structure has a loc_t typedef. The program uses the locator structure to specify simple-large-object size and location.

Line 21

Line 21 defines a single global C variable. The cpfl character array stores the name of a temporary file. This named file is the location for the simple-large-object raster image of cat_picture that the database server writes.

Lines 22 to 24

The main() function is the point at which program execution begins. The first argument, argc, is an integer that gives the number of arguments submitted on the command line. The second argument, argv[], is a pointer to an array of character strings that contain the command-line arguments. The dispcat_pic program expects only the argv[1] argument, which is optional, to specify the name of the database to access. If argv[1] is not present, the program opens the stores7 database.

26 char ans[BUFFSZ];

27 long ret, exp_chk2();

28 char db_msg[ BUFFSZ + 1 ];


	29	 	EXEC SQL BEGIN DECLARE SECTION;

30 char db_name[20];

31 char description[16];

32 EXEC SQL END DECLARE SECTION;

33 printf("DISPCAT_PIC Sample ESQL Program running.\n\n");

34 if (argc > 2) /* correct no. of args? */

35 {

36 printf("\nUsage: %s [database]\nIncorrect no. of argument(s)\n",

37 argv[0]);

38 printf("DISPCAT_PIC Sample Program over.\n\n");

39 exit(1);

40 }

41 strcpy(db_name, "stores7");

42 if(argc == 2)

43 strcpy(db_name, argv[1]);

44 EXEC SQL connect to :db_name;

45 sprintf(db_msg, "CONNECT TO %s",db_name);

46 if(exp_chk2(db_msg, NOWARNNOTIFY) < 0)

47 {

48 printf("DISPCAT_PIC Sample Program over.\n\n");

49 exit(1);

50 }

Continued on page 8-54

Lines 26 to 32

Lines 26 to 28 define the C variables that are local in scope to the main() function. The ans[BUFFSZ] array is the buffer that receives input from the user, namely the catalog number for the associated cat_picture column. Line 27 defines a long integer (ret) for the value that exp_chk2() returns and declares exp_chk2() as a function that returns a long. The db_msg[BUFFSZ + 1] character array holds the form of the CONNECT statement used to open the database. If an error occurs while the CONNECT executes, the string in db_msg is passed into the exp_chk2() function to identify the cause of the error.

Lines 29 to 32 define the ESQL/C host variables that are local to the main() function. A host variable receives data that is fetched from a table and supplies data that is written to a table. The db_name[20] character array is a host variable that stores the database name if the user specifies one on the command line. The description variable holds the value that the user entered, which is to be stored in the column of the stock table.

Lines 34 to 50

These lines interpret the command-line arguments and open the database. Line 34 checks whether more than two arguments are entered on the command line. If so, dispcat_pic displays a message to show the arguments that it expects and then it terminates. Line 41 assigns the default database name of stores7 to the db_name host variable. The program opens this database if the user does not enter a command-line argument.

The program then tests whether the number of command-line arguments is equal to 2. If so, dispcat_pic assumes that the second argument, argv[1], is the name of the database that the user wants to open. Line 43 uses the strcpy() function to copy the name of the database from the argv[1] command line into the db_name host variable. The program then executes the CONNECT statement (line 44) to establish a connection to the default database server and open the specified database (in db_name).

The program reproduces the CONNECT statement in the db_msg[] array (line 45). It does so for the sake of the exp_chk2() call on line 46, which takes as its argument the name of a statement. Line 46 calls the exp_chk2() function to check on the outcome. This call to exp_chk2() specifies the NOWARNNOTIFY argument to prevent the display of warnings that CONNECT generates.

51 if(sqlca.sqlwarn.sqlwarn3 != 'W')

52 {

53 printf("\nThis program does not work with the INFORMIX-SE");

54 printf("Server\n");

55 EXEC SQL disconnect current;

56 printf("\nDISPCAT_PIC Sample Program over.\n\n");

57 exit(1);

58 }

59 printf("Connected to %s\n", db_name);

60 ++argv;


	61	 	while(1)

62 {

63 strcpy(cpfl, "./cpfl.XXXXXX");

64 if(!mktemp(cpfl))

65 {

66 printf("** Cannot create temporary file for catalog picture.\n");

67 EXEC SQL disconnect current;

68 printf("\nDISPCAT_PIC Sample Program over.\n\n");

69 exit(1);

70 }

71 printf("\nEnter catalog number: "); /* prompt for cat. number */

72 if(!getans(ans, 6))

73 continue;

74 printf("\n");

75 if(rstol(ans, &cat_num)) /* cat_num string to long */

76 {

77 printf("** Cannot convert catalog number '%s' to integer\n",

78 ans);

79 EXEC SQL disconnect current;

80 printf("\nDISPCAT_PIC Sample Program over.\n\n");

81 exit(1);

82 }

Continued on page 8-56

Lines 51 to 60

ODS

After CONNECT successfully opens the database, it stores information about the database server in the sqlca.sqlwarn array. Because the dispcat_pic program handles simple-large-object data types that only the OnLine Dynamic Server and Universal Server database servers support, line 51 checks the type of database server. If the sqlwarn3 element of sqlca.sqlwarn is set to W, the established connection is to an OnLine Dynamic Server or Universal Server database server. Otherwise, the program notifies the user that it cannot continue and exits. The program has established the validity of the database server and now displays the name of the database that is opened (line 59).

Lines 61 to 70

The while(1) on line 61 begins the main processing loop within dispcat_pic. First the loop creates a uniquely named file to receive cat_picture. Line 63 copies the name of the temporary file to the cpfl[] array. The UNIX mktemp() function (line 64) creates a unique filename, with cpfl[] as the argument. If mktemp() cannot create a unique filename, it returns 0; lines 66 to 69 display a message to the user and exit.

Lines 71 to 74

Line 71 prompts the user to enter a catalog number for the cat_picture column that the user wants to see. Line 72 calls getans() to receive the catalog number that the user inputs. The arguments for getans() are the address in which the input is stored, ans[], and the maximum length of the input that is expected, including the null terminator. If the input is unacceptable, getans() returns 0 and line 73 returns control to the while at the top of the loop in line 61, which causes the prompt for the catalog number to be redisplayed. For a more detailed explanation of getans(), see "Guide to the inpfuncs.c File".

Lines 75 to 82

Line 75 calls the ESQL/C library function rstol() to convert the character input string to a long data type to match the data type of the catalog_num column. If rstol() returns a nonzero value, the conversion fails and lines 77 to 82 display a message to the user, close the connection, and exit.

83 /*

84 * Prepare locator structure for select of cat_descr

85 */

86 cat_descr.loc_loctype = LOCMEMORY; /* set for 'in memory' */

87 cat_descr.loc_bufsize = -1; /* let db get buffer */

88 cat_descr.loc_mflags = 0; /* clear memory-deallocation feature */

89 cat_descr.loc_oflags = 0; /* clear loc_oflags */

90 /*

91 * Prepare locator structure for select of cat_picture

92 */

93 cat_picture.loc_loctype = LOCFNAME; /* type = named file */

94 cat_picture.loc_fname = cpfl; /* supply file name */

95 cat_picture.loc_oflags = LOC_WONLY; /* file-open mode = write */

96 cat_picture.loc_size = -1; /* size = size of file */


	97	 		/* Look up catalog number */

98 EXEC SQL select description, catalog_num, cat_descr, cat_picture

99 into :description, :cat_num, :cat_descr, :cat_picture

100 from stock, catalog

101 where catalog_num = :cat_num

102 and catalog.stock_num = stock.stock_num

103 and catalog.manu_code = stock.manu_code;

104 if((ret = exp_chk2("SELECT", WARNNOTIFY)) == 100) /* if not found */

105 {

106 printf("** Catalog number %ld not found in ", cat_num);

107 printf("catalog table.\n");

108 printf("\t OR item not found in stock table.\n");

109 if(!more_to_do())

110 break;

111 continue;

112 }

Continued on page 8-58

Lines 83 to 89

These lines define the simple-large-object location for the TEXT cat_descr column of the catalog table, as follows:

If the select is successful, ESQL/C returns the address of the allocated buffer in loc_buffer. Line 89 sets the loc_oflags file-open mode flags to 0 because the program retrieves the simple large object into memory rather than a file.

Lines 90 to 96

These lines prepare the locator structure to retrieve the BYTE cat_picture of the catalog table. Line 93 moves LOCFNAME to loc_loctype to tell ESQL/C to locate the data for cat_descr in a named file. Line 94 moves the address of the cpfl filename into loc_fname. Line 95 moves the LOC_WONLY value into the loc_oflags file-open mode flags to tell ESQL/C to open the file in write-only mode. Finally, line 96 sets loc_size to -1 to tell ESQL/C to send the BYTE data in a single transfer rather than break the value into smaller pieces and use multiple transfers.

Lines 97 to 103

These lines define a SELECT statement to retrieve the catalog_num, cat_descr, and cat_picture columns from the catalog table and the description column from the stock table for the catalog number that the user entered. The INTO clause of the SELECT statement identifies the host variables that contain the selected values. The two loc_t host variables, cat_descr and cat_picture, are listed in this clause for the TEXT and BYTE values.

Lines 104 to 112

The exp_chk2() function checks whether the SELECT statement was able to find the stock_num and manu_code for the selected row in the catalog table and in the stock table. The catalog table should not contain a row that does not have a corresponding row in the stock table. Lines 106 to 112 handle a NOT FOUND condition. If the exp_chk2() function returns 100, the row was not found; lines 106 to 108 display a message to that effect. The more_to_do() function (line 109) asks whether the user wants to continue. If the user answers n for no, a break terminates the main processing loop and control transfers to line 141 to close the database before the program terminates.

113 if(ret < 0)

114 {

115 EXEC SQL disconnect current;

116 printf("\nDISPCAT_PIC Sample Program over.\n\n");

117 exit(1);

118 }

119 printf("Displaying catalog picture for %ld...\n", cat_num);

120 if(cat_picture.loc_indicator == -1)

121 printf("\tNo picture available for catalog number %ld\n\n",

122 cat_num);

123 else

124 display_picture();

125 /*

126 * Display catalog_num and description from catalog table

127 */

128 printf("Stock Item for %ld: %s\n", cat_num, description);

129 prdesc(); /* display catalog.cat_descr */


	130	 		unlink(cpfl);  				/* remove temp file for cat_picture */

131 if(!more_to_do()) /* More to do? */

132 break; /* no, terminate loop */

133 /* If user chooses to display more catalog rows, enable the

134 * memory-deallocation feature so that ESQL/C deallocates old

135 * catalog.cat_cesc buffer before it allocates a new one.

136 */

137 cat_descr.loc_mflags = LOC_ALLOC; /* enable memory-deallocation feature */

138 }

Continued on page 8-60

Lines 113 to 118

If a runtime error occurs during the select, the program closes the current connection, notifies the user, and exits with a status of 1.

Lines 119 to 123

Line 119 notifies the user that the catalog picture is about to be displayed. If cat_picture.loc_indicator contains-1 (line 120), the cat_picture column contains a null and the program informs the user (lines 121 and 122). Execution then continues to line 128 to display the other returned column values.

Lines 124 and 125

If cat_picture is not null, the display_picture() function handles the display of the cat_picture data that the database server wrote to a temporary file. The format for the display depends on the value that you gave to the SUNVIEW conditional flag when you compiled. For more information, see "Compiling the dispcat_pic Program". For a detailed description of display_picture(), see "Lines 142 to 169".

Lines 128 and 129

These lines display the other columns that the SELECT statement returned. Line 128 displays the catalog number that is being processed and the description column from the stock table. Line 129 calls prdesc() to display the cat_descr column. For a detailed description of prdesc(), see "Guide to the prdesc.c File".

Lines 130 to 138

Line 130 deletes the file named in cpfl[], the temporary file that contains the simple-large-object image for cat_picture. The more_to_do() function then asks whether the user wants to enter more catalog numbers. If not, more_to_do() returns 0 and the program performs a break to terminate the main processing loop, close the database, and terminate the program.

If execution continues to line 137, the user has chosen to enter another catalog number. In this case, the program sets loc_mflags to the LOC_ALLOC constant to enable the memory-deallocation feature for the ESQL/C buffers (see line 88). If ESQL/C needs to allocate a larger buffer, it first deallocates the existing buffer. If loc_mflags had remained 0, ESQL/C would not deallocate the existing buffer.

The closing brace on line 138 terminates the main processing loop, which began with the while(1) on line 61. If the user wants to enter another catalog number, control returns to line 61.

139 EXEC SQL disconnect current;

140 printf("\nDISPCAT_PIC Sample Program over.\n\n");


	141	 } /* end main */

142 /*

143 * Display the sunview raster file. Note that this function works only

144 * on SUN platforms.

145 */

146

147 display_picture()

148 {

149

150 #ifdef SUNVIEW

151 int child, childstat, w;

152 static char path[] = "/bin/screenload";

153 static char *slargs[] = /* arguments for screenload */

154 {

155 "-w",

156 "-x260",

157 "-y300",

158 "-X400",

159 "-Y350",

160 cpfl,

161 (char *) 0,

162 };

163

164 if((child = fork()) == 0) /* child displays cat_picture */

165 {

166 execv(path, slargs); /* execute screenload */

167 fprintf(stderr, "\tCouldn't execute %s, errno %d\n", path, errno);

168 exit(1);

169 }

Continued on page 8-62

Line 139 to 141

When a break statement (line 132) terminates the main processing loop that the while(1) on line 61 began, control transfers to line 139, which closes the database and the connection to the default database server. The closing brace on line 141 terminates the main() function on line 22 and terminates the program.

Lines 142 to 169

Line 147 begins the declaration of the display_picture() function that displays the BYTE cat_picture value. This function can display the cat_picture column only if the program is compiled with the -DSUNVIEW option. For more information, see "Compiling the dispcat_pic Program". At compile time, the esql command executes line 150 to check whether SUNVIEW is defined. It includes lines 151 to 177 in display_picture() only if SUNVIEW is defined. Otherwise, it includes only line 180 to print a message and return to main().

Lines 151 to 162 define variables that participate in the storage and display of cat_picture, as follows.

Variable Description

child

Receives the process ID of the child process that display_picture() creates with fork().

childstat

Stores the status of the child process that wait() returns.

w

The value that wait() returns, the process ID of the terminated child process.

path

Stores the location and name of screenload, the program that displays the cat_picture image from cpfl.

slargs

Stores the command-line arguments for screenload, the program that displays the cat_picture image, as follows:

-w

Specifies the background color.

-x260, y300

Specifies the location of the picture in pixels.

-X400, -Y350

Specifies the size of the picture in pixels.

cpfl

The name of the file that contains the picture.

(char *) 0

The null terminator for the slargs array.

The database server writes the image from the cat_picture column to the file named in cpfl. To display the image, display_picture() calls the fork() system function to create a second process. The display_picture() program checks the value that fork() returns to distinguish the parent from the child process. The fork() returns 0 to the child process and the child process ID to the parent, so that only the child process executes lines 166 to 168. Line 166 executes the program named in path, the Sun screenload utility program. The screenload utility program overlays dispcat_pic in the child process and executes with the command-line arguments that are passed in slargs[]. Lines 167 and 168, which display an error message and exit, only execute if the system is unable to launch screenload.

170 /*

171 * parent waits for child to finish

172 */

173 if((w = wait(&childstat)) != child && w != -1)

174 {

175 printf("Error or orphaned child %d", w);

176 exit(-1);

177 }

178 #endif /* SUNVIEW */


	179	 #ifndef SUNVIEW

180 printf("** Cannot print catalog picture.\n");

181 #endif /* not SUNVIEW */

182 }

183 /* prdesc() prints cat_desc for a row in the catalog table */

184 #include "prdesc.c"

185 /*

186 * The inpfuncs.c file contains the following functions used in this

187 * program:

188 * more_to_do() - asks the user to enter 'y' or 'n' to indicate

189 * whether to run the main program loop again.

190 *

191 * getans(ans, len) - accepts user input, up to 'len' number of

192 * characters and puts it in 'ans'

193 */

194 #include "inpfuncs.c"

Continued on page 8-64

Line 170 to 178

The parent process calls the wait() system function (line 173) and waits for the child process to terminate. The wait() system call returns the process ID of the process that terminates. Line 173 checks that this value, w, is the same as child, the value that fork() returns. It also checks that the value is not -1, which indicates that an error or an interrupt occurred in the child process. If either error occurs, lines 175 and 176 display a message and exit the program.

Lines 179 to 182

The esql command executes lines 179 and 181 at compile time. The endif directive marks the end of the text to include in the display_picture() function if SUNVIEW is defined. Line 179 checks if SUNVIEW is not defined.

Lines 183 and 184

Several of the ESQL/C simple-large-object demonstration programs call the prdesc() function. To avoid having the function in each program, the function is put in its own source file. Each program that calls prdesc() includes the prdesc.c source file. Since prdesc() does not contain any ESQL/C statements, the program can include it with the C #include preprocessor statement (instead of the ESQL/C include directive). For a description of this function, see "Guide to the prdesc.c File".

Lines 185 to 194

Several of the ESQL/C demonstration programs also call the more_to_do() and getans() functions. These functions are also broken out into a separate C source file and included in the appropriate demonstration program. Neither of these functions contain ESQL/C, so the program can use the C #include preprocessor statement to include the files. For a description of these functions, see "Guide to the inpfuncs.c File".

195 /*

196 * The exp_chk.ec file contains the exception handling functions to

197 * check the SQLSTATE status variable to see if an error has occurred

198 * following an SQL statement. If a warning or an error has

199 * occurred, exp_chk2() executes the GET DIAGNOSTICS statement and

200 * displays the detail for each exception that is returned.

201 */

202 EXEC SQL include exp_chk.ec;

Lines 195 to 202

The exp_chk2() function examines the SQLSTATE status variable to determine the outcome of an SQL statement. Because many demonstration programs use exception checking, the exp_chk2() function and its supporting functions have been broken out into a separate exp_chk.ec source file. The dispcat_pic program must use the ESQL/C include directive to include this file because the exception-handling functions use ESQL/C statements. For a description of the exp_chk.ec source file, see "Guide to the exp_chk.ec File".

Tip: In a production environment, functions such as prdesc(), more_to_do(), getans(), and exp_chk2() would be put into C libraries and included on the command line of the ESQL/C program at compile time.

Guide to the prdesc.c File

The prdesc.c file contains the prdesc() function. This function sets the pointer p to the address that is provided in the loc_buffer field of the locator structure to access the simple large object. The function then reads the text from the buffer 80 bytes at a time up to the size specified in loc_size. This function is used in several of the simple-large-object demonstration programs so it is in a separate file and included in the appropriate source files.

1 /* prdesc() prints cat_desc for a row in the catalog table */

2

3 prdesc()

4 {

5 long size;

6 char shdesc[81], *p;

7

8 size = cat_descr.loc_size; /* get size of data */

9 printf("Description for %ld:\n", cat_num);

10 p = cat_descr.loc_buffer; /* set p to buffer addr */

11

12 /* print buffer 80 characters at a time */

13 while(size >= 80)

14 {

15 ldchar(p, 80, shdesc); /* mv from buffer to shdesc */

16 printf("\n%80s", shdesc); /* display it */

17 size -= 80; /* decrement length */

18 p += 80; /* bump p by 80 */

19 }

20 strncpy(shdesc, p, size);

21 shdesc[size] = '\0';

22 printf("%-s\n", shdesc); /* display last segment */

23 }

Lines 3 to 22

Lines 3 to 22 make up the prdesc() function, which displays the cat_descr column of the catalog table. Line 5 defines size, a long integer that prdesc() initializes with the value in cat_descr.loc_size. Line 6 defines shdesc[81], an array into which prdesc() temporarily moves 80-byte chunks of the cat_descr text for output. Line 6 also defines *p, a pointer that marks the current position in the buffer as it is being displayed.

In loc_size, the database server returns the size of the buffer that it allocates for a simple large object. Line 8 moves cat_descr.loc_size to size. Line 9 displays the string "Description for:" as a header for the cat_descr text. Line 10 sets the p pointer to the buffer address that the database server returned in cat_descr.loc_size.

Line 13 begins the loop that displays the cat_descr text to the user. The while() repeats the loop until size is less than 80. Line 14 begins the body of the loop. The ESQL/C ldchar() library function copies 80 bytes from the current position in the buffer, which p addresses, to shdesc[] and removes any trailing blanks. Line 16 prints the contents of shdesc[]. Line 17 subtracts 80 from size to account for the portion of the buffer that was just printed. Line 18, the last in the loop, adds 80 to p to move it past the portion of the buffer that was just displayed.

The process of displaying cat_descr.loc_size 80 bytes at a time continues until fewer than 80 characters are left to be displayed (size < 80). Line 20 copies the remainder of the buffer into shdesc[] for the length of size. Line 21 appends a null to shdesc[size] to mark the end of the array and line 22 displays shdesc[].

Guide to the inpfuncs.c File

The inpfuncs.c file contains the following two functions:

Because these functions are used in several ESQL/C demonstration programs, they are in a separate file and included in the appropriate demonstration source files.

1 /* The inpfuncs.c file contains functions useful in character-based

2 input for a C program.

3 */


	4	 #include <ctype.h>

5 #ifndef LCASE

6 #define LCASE(c) (isupper(c) ? tolower(c) : (c))

7 #endif

8 /*

9 Accepts user input, up to 'len' number of characters and returns

10 it in 'ans'

11 */

12 #define BUFSIZE 512

13 getans(ans, len)

14 char *ans;

15 int len;

16 {

17 char buf[BUFSIZE + 1];

18 int c, n = 0;

19 while((c = getchar()) != '\n' && n < BUFSIZE)

20 buf[n++] = c;

21 buf[n] = '\0';

22 if(n > 1 && n >= len)

23 {

24 printf("Input exceeds maximum length");

25 return 0;

26 }

27 if(len <= 1)

28 *ans = buf[0];

29 else

30 strncpy(ans, buf, len);

31 return 1;

32 }

Continued on page 8-70

Lines 4 to 7

Line 4 includes the UNIX ctype.h header file. This header file provides the definitions of the islower() and tolower() macros used in the definition of the LCASE() macro (defined on line 6). The program only defines the LCASE macro if it has not yet been defined in the program.

Lines 12 to 32

The BUFSIZE constant (line 12) defines the size of the character buffer used in the getans() function. Lines 13 to 32 constitute the getans() function. The getans() function uses the getchar() standard library function to accept input from the user. Lines 14 and 15 define the arguments for getans(), the address of the buffer (ans) where it copies the input, and the maximum number of characters (len) that the calling function expects. Line 17 defines buf[], an input buffer array. The int variable c (line 18) receives the character that getchar() returned. The second integer defined on line 18, n, is used to subscript the buf[] input buffer.

Line 19 calls getchar() to receive input from the user until a \n newline character is encountered or until the maximum input is received; that is, n is not less than BUFFSZ. Line 20 moves the input character c into the current position in buf[]. Line 21 places a null terminator at the end of the input, buf[n].

Lines 22 to 26 check whether the number of characters received, n, is less than the number of characters expected, len. If not, line 24 displays a message to the user and line 25 returns 0 to the calling function to indicate that an error occurred. Line 27 checks whether one or more characters were entered. If the expected number of characters, len, is less than or equal to 1, line 28 moves only a single character to the address that the ans calling function gives. If only one character is expected, getans() does not append a null terminator to the input. If the length of the input is greater than 1, line 30 copies the user's input to the address that the calling function (ans) supplies. Line 31 returns 1 to the calling function to indicate successful completion.

33 /*

34 * Ask user if there is more to do

35 */

36 more_to_do()

37 {

38 char ans;


	39	 	do

40 {

41 printf("\n**** More? (y/n) ... ");

42 getans(&ans, 1);

43 } while((ans = LCASE(ans)) != 'y' && ans != 'n');

44 return (ans == 'n') ? 0 : 1;

45 }

Lines 33 to 45

The more_to_do () function displays "More? (y/n)..." to ask whether the user wants to continue program execution. The more_to_do() function does not have any input arguments. Line 38 defines a one-character field, ans, to receive the user's response. The condition expressed on line 43 causes the question to be redisplayed until the user answers y(yes) or n(no). The LCASE macro converts the user's answer to lowercase letters for the comparison. Line 42 calls getans() to accept the user's input. Once the user answers yes or no, control passes to line 44, which returns 1 for yes and 0 for no to the calling function.




Informix-ESQL/C Programmer's Manual, version 9.1
Copyright © 1998, Informix Software, Inc. All rights reserved.