Line data Source code
1 : #include <config.h>
2 :
3 : #include <stdio.h>
4 :
5 : #if HAVE_STDLIB_H
6 : #include <stdlib.h>
7 : #endif /* HAVE_STDLIB_H */
8 :
9 : #if HAVE_STRING_H
10 : #include <string.h>
11 : #endif /* HAVE_STRING_H */
12 :
13 : #include <ctpublic.h>
14 : #include "common.h"
15 :
16 : #define MAX(X,Y) (((X) > (Y)) ? (X) : (Y))
17 : #define MIN(X,Y) (((X) < (Y)) ? (X) : (Y))
18 :
19 : CS_RETCODE ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg);
20 : CS_RETCODE ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * errmsg);
21 : static CS_RETCODE ex_display_header(CS_INT numcols, CS_DATAFMT columns[]);
22 : static CS_INT ex_display_dlen(CS_DATAFMT *column);
23 : static CS_INT ex_display_results(CS_COMMAND * cmd);
24 :
25 : typedef struct _ex_column_data
26 : {
27 : CS_SMALLINT indicator;
28 : CS_CHAR *value;
29 : CS_INT valuelen;
30 : }
31 : EX_COLUMN_DATA;
32 :
33 : /* Testing: array binding of result set */
34 : int
35 8 : main(int argc, char *argv[])
36 : {
37 : CS_CONTEXT *ctx;
38 : CS_CONNECTION *conn;
39 : CS_COMMAND *cmd;
40 8 : int verbose = 0;
41 :
42 : CS_RETCODE ret;
43 :
44 : CS_INT datalength;
45 : CS_SMALLINT nullind;
46 : CS_SMALLINT notnullind;
47 :
48 : CS_CHAR cmdbuf[4096];
49 :
50 : CS_DATAFMT datafmt;
51 : CS_DATAFMT srcfmt;
52 : CS_DATAFMT destfmt;
53 : CS_INT intvar;
54 : CS_SMALLINT smallintvar;
55 : CS_FLOAT floatvar;
56 : CS_MONEY moneyvar;
57 : CS_BINARY binaryvar;
58 : char moneystring[10];
59 : char rpc_name[15];
60 : CS_INT destlen;
61 :
62 :
63 :
64 8 : printf("%s: submit a stored procedure using ct_setparam \n", __FILE__);
65 : if (verbose) {
66 : printf("Trying login\n");
67 : }
68 8 : ret = try_ctlogin(&ctx, &conn, &cmd, verbose);
69 8 : if (ret != CS_SUCCEED) {
70 0 : fprintf(stderr, "Login failed\n");
71 0 : return 1;
72 : }
73 :
74 8 : ct_callback(ctx, NULL, CS_SET, CS_CLIENTMSG_CB, (CS_VOID *) ex_clientmsg_cb);
75 :
76 8 : ct_callback(ctx, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID *) ex_servermsg_cb);
77 :
78 : /* do not test error */
79 8 : ret = run_command(cmd, "IF OBJECT_ID('sample_rpc') IS NOT NULL DROP PROCEDURE sample_rpc");
80 :
81 8 : strcpy(cmdbuf, "create proc sample_rpc (@intparam int, \
82 : @sintparam smallint output, @floatparam float output, \
83 : @moneyparam money output, \
84 : @dateparam datetime output, @charparam char(20) output, \
85 : @binaryparam varbinary(2000) output) \
86 : as ");
87 :
88 8 : strcat(cmdbuf, "select @intparam, @sintparam, @floatparam, @moneyparam, \
89 : @dateparam, @charparam, @binaryparam \
90 : select @sintparam = @sintparam + @intparam \
91 : select @floatparam = @floatparam + @intparam \
92 : select @moneyparam = @moneyparam + convert(money, @intparam) \
93 : select @dateparam = getdate() \
94 : select @charparam = \'The char parameters\' \
95 : select @binaryparam = @binaryparam \
96 : print \'This is the message printed out by sample_rpc.\'");
97 :
98 8 : ret = run_command(cmd, cmdbuf);
99 :
100 8 : if (ret != CS_SUCCEED) {
101 0 : fprintf(stderr, "create proc failed\n");
102 0 : return 1;
103 : }
104 :
105 : /*
106 : * Assign values to the variables used for parameter passing.
107 : */
108 :
109 8 : intvar = 2;
110 8 : smallintvar = 234;
111 8 : floatvar = 0.12;
112 8 : binaryvar = (CS_BINARY) 0xff;
113 8 : strcpy(rpc_name, "sample_rpc");
114 8 : strcpy(moneystring, "300.90");
115 :
116 : /*
117 : * Clear and setup the CS_DATAFMT structures used to convert datatypes.
118 : */
119 :
120 8 : memset(&srcfmt, 0, sizeof(CS_DATAFMT));
121 : srcfmt.datatype = CS_CHAR_TYPE;
122 8 : srcfmt.maxlength = strlen(moneystring);
123 8 : srcfmt.precision = 5;
124 8 : srcfmt.scale = 2;
125 : srcfmt.locale = NULL;
126 :
127 8 : memset(&destfmt, 0, sizeof(CS_DATAFMT));
128 8 : destfmt.datatype = CS_MONEY_TYPE;
129 8 : destfmt.maxlength = sizeof(CS_MONEY);
130 8 : destfmt.precision = 5;
131 8 : destfmt.scale = 2;
132 : destfmt.locale = NULL;
133 :
134 : /*
135 : * Convert the string representing the money value
136 : * to a CS_MONEY variable. Since this routine does not have the
137 : * context handle, we use the property functions to get it.
138 : */
139 8 : if ((ret = ct_cmd_props(cmd, CS_GET, CS_PARENT_HANDLE, &conn, CS_UNUSED, NULL)) != CS_SUCCEED) {
140 0 : fprintf(stderr, "ct_cmd_props() failed");
141 0 : return 1;
142 : }
143 8 : if ((ret = ct_con_props(conn, CS_GET, CS_PARENT_HANDLE, &ctx, CS_UNUSED, NULL)) != CS_SUCCEED) {
144 0 : fprintf(stderr, "ct_con_props() failed");
145 0 : return 1;
146 : }
147 8 : ret = cs_convert(ctx, &srcfmt, (CS_VOID *) moneystring, &destfmt, &moneyvar, &destlen);
148 8 : if (ret != CS_SUCCEED) {
149 0 : fprintf(stderr, "cs_convert() failed");
150 0 : return 1;
151 : }
152 :
153 : /*
154 : * Send the RPC command for our stored procedure.
155 : */
156 8 : if ((ret = ct_command(cmd, CS_RPC_CMD, rpc_name, CS_NULLTERM, CS_NO_RECOMPILE)) != CS_SUCCEED) {
157 0 : fprintf(stderr, "ct_command(CS_RPC_CMD) failed");
158 0 : return 1;
159 : }
160 :
161 8 : nullind = -1;
162 8 : notnullind = 0;
163 : /*
164 : * Clear and setup the CS_DATAFMT structure, then pass
165 : * each of the parameters for the RPC.
166 : */
167 8 : memset(&datafmt, 0, sizeof(datafmt));
168 8 : strcpy(datafmt.name, "@intparam");
169 8 : datafmt.namelen = CS_NULLTERM;
170 8 : datafmt.datatype = CS_INT_TYPE;
171 8 : datafmt.maxlength = CS_UNUSED;
172 8 : datafmt.status = CS_INPUTVALUE;
173 : datafmt.locale = NULL;
174 :
175 8 : datalength = CS_SIZEOF(CS_INT);
176 :
177 8 : if ((ret = ct_setparam(cmd, &datafmt, (CS_VOID *) & intvar, &datalength, ¬nullind)) != CS_SUCCEED) {
178 0 : fprintf(stderr, "ct_setparam(int) failed");
179 0 : return 1;
180 : }
181 :
182 8 : strcpy(datafmt.name, "@sintparam");
183 8 : datafmt.namelen = CS_NULLTERM;
184 8 : datafmt.datatype = CS_SMALLINT_TYPE;
185 8 : datafmt.maxlength = 255;
186 8 : datafmt.status = CS_RETURN;
187 8 : datafmt.locale = NULL;
188 :
189 8 : datalength = CS_SIZEOF(CS_SMALLINT);
190 :
191 8 : if ((ret = ct_setparam(cmd, &datafmt, (CS_VOID *) & smallintvar, &datalength, ¬nullind)) != CS_SUCCEED) {
192 0 : fprintf(stderr, "ct_setparam(smallint) failed");
193 0 : return 1;
194 : }
195 :
196 8 : strcpy(datafmt.name, "@floatparam");
197 8 : datafmt.namelen = CS_NULLTERM;
198 8 : datafmt.datatype = CS_FLOAT_TYPE;
199 8 : datafmt.maxlength = 255;
200 8 : datafmt.status = CS_RETURN;
201 8 : datafmt.locale = NULL;
202 :
203 8 : datalength = CS_SIZEOF(CS_FLOAT);
204 :
205 8 : if ((ret = ct_setparam(cmd, &datafmt, (CS_VOID *) & floatvar, &datalength, ¬nullind)) != CS_SUCCEED) {
206 0 : fprintf(stderr, "ct_setparam(float) failed");
207 0 : return 1;
208 : }
209 :
210 :
211 8 : strcpy(datafmt.name, "@moneyparam");
212 8 : datafmt.namelen = CS_NULLTERM;
213 8 : datafmt.datatype = CS_MONEY_TYPE;
214 8 : datafmt.maxlength = 255;
215 8 : datafmt.status = CS_RETURN;
216 8 : datafmt.locale = NULL;
217 :
218 8 : datalength = CS_SIZEOF(CS_MONEY);
219 :
220 8 : if ((ret = ct_setparam(cmd, &datafmt, (CS_VOID *) & moneyvar, &datalength, ¬nullind)) != CS_SUCCEED) {
221 0 : fprintf(stderr, "ct_setparam(money) failed");
222 0 : return 1;
223 : }
224 :
225 8 : strcpy(datafmt.name, "@dateparam");
226 8 : datafmt.namelen = CS_NULLTERM;
227 8 : datafmt.datatype = CS_DATETIME4_TYPE;
228 8 : datafmt.maxlength = 255;
229 8 : datafmt.status = CS_RETURN;
230 8 : datafmt.locale = NULL;
231 :
232 : /*
233 : * The datetime variable is filled in by the RPC so pass NULL for
234 : * the data, 0 for data length, and -1 for the indicator arguments.
235 : */
236 :
237 8 : datalength = 0;
238 :
239 8 : if ((ret = ct_setparam(cmd, &datafmt, NULL, &datalength, &nullind)) != CS_SUCCEED) {
240 0 : fprintf(stderr, "ct_setparam(datetime4) failed");
241 0 : return 1;
242 : }
243 8 : strcpy(datafmt.name, "@charparam");
244 8 : datafmt.namelen = CS_NULLTERM;
245 8 : datafmt.datatype = CS_CHAR_TYPE;
246 8 : datafmt.maxlength = 60;
247 8 : datafmt.status = CS_RETURN;
248 8 : datafmt.locale = NULL;
249 :
250 :
251 8 : datalength = 0;
252 :
253 : /*
254 : * The character string variable is filled in by the RPC so pass NULL
255 : * for the data 0 for data length, and -1 for the indicator arguments.
256 : */
257 8 : if ((ret = ct_setparam(cmd, &datafmt, NULL, &datalength, &nullind)) != CS_SUCCEED) {
258 0 : fprintf(stderr, "ct_setparam(char) failed");
259 0 : return 1;
260 : }
261 :
262 8 : strcpy(datafmt.name, "@binaryparam");
263 8 : datafmt.namelen = CS_NULLTERM;
264 8 : datafmt.datatype = CS_LONGBINARY_TYPE;
265 8 : datafmt.maxlength = 2000;
266 8 : datafmt.status = CS_RETURN;
267 8 : datafmt.locale = NULL;
268 :
269 8 : datalength = CS_SIZEOF(CS_BINARY);
270 8 : nullind = -1;
271 :
272 8 : if ((ret = ct_setparam(cmd, &datafmt, (CS_VOID *) & binaryvar, &datalength, ¬nullind)) != CS_SUCCEED) {
273 0 : fprintf(stderr, "ct_setparam(binary) failed");
274 0 : return 1;
275 : }
276 :
277 : /*
278 : * Send the command to the server
279 : */
280 8 : if (ct_send(cmd) != CS_SUCCEED) {
281 0 : fprintf(stderr, "ct_send(RPC) failed");
282 0 : return 1;
283 : }
284 :
285 8 : ret = ex_display_results(cmd);
286 8 : if (ret != CS_SUCCEED) {
287 0 : fprintf(stderr, "ex_display_results failed\n");
288 0 : return 1;
289 : }
290 :
291 8 : intvar = 3;
292 :
293 8 : if (ct_send(cmd) != CS_SUCCEED) {
294 0 : fprintf(stderr, "ct_send(RPC) failed");
295 0 : return 1;
296 : }
297 :
298 8 : ret = ex_display_results(cmd);
299 8 : if (ret != CS_SUCCEED) {
300 0 : fprintf(stderr, "ex_display_results failed\n");
301 0 : return 1;
302 : }
303 :
304 8 : run_command(cmd, "DROP PROCEDURE sample_rpc");
305 :
306 : if (verbose) {
307 : printf("Trying logout\n");
308 : }
309 8 : ret = try_ctlogout(ctx, conn, cmd, verbose);
310 8 : if (ret != CS_SUCCEED) {
311 0 : fprintf(stderr, "Logout failed\n");
312 0 : return 1;
313 : }
314 :
315 : return 0;
316 : }
317 :
318 : static CS_INT
319 16 : ex_display_results(CS_COMMAND * cmd)
320 : {
321 :
322 : CS_RETCODE ret;
323 : CS_INT res_type;
324 : CS_INT num_cols;
325 : EX_COLUMN_DATA *coldata;
326 : CS_DATAFMT *outdatafmt;
327 16 : CS_INT row_count = 0;
328 : CS_INT rows_read;
329 : CS_INT disp_len;
330 : CS_SMALLINT msg_id;
331 : int i, j;
332 :
333 : /*
334 : * Process the results of the RPC.
335 : */
336 76 : while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
337 44 : switch ((int) res_type) {
338 12 : case CS_ROW_RESULT:
339 : case CS_PARAM_RESULT:
340 : case CS_STATUS_RESULT:
341 : /*
342 : * Print the result header based on the result type.
343 : */
344 12 : switch ((int) res_type) {
345 4 : case CS_ROW_RESULT:
346 4 : printf("\nROW RESULTS\n");
347 4 : break;
348 :
349 4 : case CS_PARAM_RESULT:
350 4 : printf("\nPARAMETER RESULTS\n");
351 4 : break;
352 :
353 4 : case CS_STATUS_RESULT:
354 4 : printf("\nSTATUS RESULTS\n");
355 4 : break;
356 : }
357 12 : fflush(stdout);
358 :
359 : /*
360 : * All three of these result types are fetchable.
361 : * Since the result model for rpcs and rows have
362 : * been unified in the New Client-Library, we
363 : * will use the same routine to display them
364 : */
365 :
366 : /*
367 : * Find out how many columns there are in this result set.
368 : */
369 12 : ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
370 12 : if (ret != CS_SUCCEED) {
371 0 : fprintf(stderr, "ct_res_info(CS_NUMDATA) failed");
372 0 : return 1;
373 : }
374 :
375 : /*
376 : * Make sure we have at least one column
377 : */
378 12 : if (num_cols <= 0) {
379 0 : fprintf(stderr, "ct_res_info(CS_NUMDATA) returned zero columns");
380 0 : return 1;
381 : }
382 :
383 : /*
384 : * Our program variable, called 'coldata', is an array of
385 : * EX_COLUMN_DATA structures. Each array element represents
386 : * one column. Each array element will re-used for each row.
387 : *
388 : * First, allocate memory for the data element to process.
389 : */
390 12 : coldata = (EX_COLUMN_DATA *) malloc(num_cols * sizeof(EX_COLUMN_DATA));
391 12 : if (coldata == NULL) {
392 0 : fprintf(stderr, "malloc coldata failed \n");
393 0 : return 1;
394 : }
395 :
396 12 : outdatafmt = (CS_DATAFMT *) malloc(num_cols * sizeof(CS_DATAFMT));
397 12 : if (outdatafmt == NULL) {
398 0 : free(coldata);
399 0 : fprintf(stderr, "malloc outdatafmt failed \n");
400 0 : return 1;
401 : }
402 :
403 68 : for (i = 0; i < num_cols; i++) {
404 56 : ret = ct_describe(cmd, (i + 1), &outdatafmt[i]);
405 56 : if (ret != CS_SUCCEED) {
406 0 : fprintf(stderr, "ct_describe failed \n");
407 0 : break;
408 : }
409 :
410 56 : outdatafmt[i].maxlength = ex_display_dlen(&outdatafmt[i]) + 1;
411 56 : outdatafmt[i].datatype = CS_CHAR_TYPE;
412 56 : outdatafmt[i].format = CS_FMT_NULLTERM;
413 :
414 56 : coldata[i].value = (CS_CHAR *) malloc(outdatafmt[i].maxlength);
415 56 : coldata[i].value[0] = 0;
416 : if (coldata[i].value == NULL) {
417 : fprintf(stderr, "malloc coldata.value failed \n");
418 : ret = CS_FAIL;
419 : break;
420 : }
421 :
422 56 : ret = ct_bind(cmd, (i + 1), &outdatafmt[i], coldata[i].value, &coldata[i].valuelen,
423 : & coldata[i].indicator);
424 56 : if (ret != CS_SUCCEED) {
425 0 : fprintf(stderr, "ct_bind failed \n");
426 0 : break;
427 : }
428 : }
429 12 : if (ret != CS_SUCCEED) {
430 0 : for (j = 0; j < i; j++) {
431 0 : free(coldata[j].value);
432 : }
433 0 : free(coldata);
434 0 : free(outdatafmt);
435 0 : return 1;
436 : }
437 :
438 12 : ex_display_header(num_cols, outdatafmt);
439 :
440 36 : while (((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
441 12 : &rows_read)) == CS_SUCCEED) || (ret == CS_ROW_FAIL)) {
442 : /*
443 : * Increment our row count by the number of rows just fetched.
444 : */
445 12 : row_count = row_count + rows_read;
446 :
447 : /*
448 : * Check if we hit a recoverable error.
449 : */
450 12 : if (ret == CS_ROW_FAIL) {
451 0 : printf("Error on row %d.\n", row_count);
452 0 : fflush(stdout);
453 : }
454 :
455 : /*
456 : * We have a row. Loop through the columns displaying the
457 : * column values.
458 : */
459 56 : for (i = 0; i < num_cols; i++) {
460 : /*
461 : * Display the column value
462 : */
463 56 : printf("%s", coldata[i].value);
464 56 : fflush(stdout);
465 :
466 : /*
467 : * If not last column, Print out spaces between this
468 : * column and next one.
469 : */
470 56 : if (i != num_cols - 1) {
471 44 : disp_len = ex_display_dlen(&outdatafmt[i]);
472 44 : disp_len -= coldata[i].valuelen - 1;
473 784 : for (j = 0; j < disp_len; j++) {
474 740 : fputc(' ', stdout);
475 : }
476 : }
477 : }
478 12 : printf("\n");
479 12 : fflush(stdout);
480 : }
481 :
482 : /*
483 : * Free allocated space.
484 : */
485 56 : for (i = 0; i < num_cols; i++) {
486 56 : free(coldata[i].value);
487 : }
488 12 : free(coldata);
489 12 : free(outdatafmt);
490 :
491 : /*
492 : * We're done processing rows. Let's check the final return
493 : * value of ct_fetch().
494 : */
495 12 : switch ((int) ret) {
496 12 : case CS_END_DATA:
497 : /*
498 : * Everything went fine.
499 : */
500 12 : printf("All done processing rows.\n");
501 12 : fflush(stdout);
502 : break;
503 :
504 0 : case CS_FAIL:
505 : /*
506 : * Something terrible happened.
507 : */
508 0 : fprintf(stderr, "ct_fetch returned CS_FAIL\n");
509 0 : return 1;
510 : break;
511 :
512 0 : default:
513 : /*
514 : * We got an unexpected return value.
515 : */
516 0 : fprintf(stderr, "ct_fetch returned %d\n", ret);
517 0 : return 1;
518 : break;
519 :
520 : }
521 12 : break;
522 :
523 0 : case CS_MSG_RESULT:
524 0 : ret = ct_res_info(cmd, CS_MSGTYPE, (CS_VOID *) & msg_id, CS_UNUSED, NULL);
525 0 : if (ret != CS_SUCCEED) {
526 0 : fprintf(stderr, "ct_res_info(msg_id) failed");
527 0 : return 1;
528 : }
529 0 : printf("ct_result returned CS_MSG_RESULT where msg id = %d.\n", msg_id);
530 0 : fflush(stdout);
531 0 : break;
532 :
533 : case CS_CMD_SUCCEED:
534 : /*
535 : * This means no rows were returned.
536 : */
537 : break;
538 :
539 : case CS_CMD_DONE:
540 : /*
541 : * Done with result set.
542 : */
543 : break;
544 :
545 10 : case CS_CMD_FAIL:
546 : /*
547 : * The server encountered an error while
548 : * processing our command.
549 : */
550 10 : fprintf(stderr, "ct_results returned CS_CMD_FAIL.");
551 10 : break;
552 :
553 0 : default:
554 : /*
555 : * We got something unexpected.
556 : */
557 0 : fprintf(stderr, "ct_results returned unexpected result type.");
558 0 : return CS_FAIL;
559 : }
560 : }
561 :
562 : /*
563 : * We're done processing results. Let's check the
564 : * return value of ct_results() to see if everything
565 : * went ok.
566 : */
567 16 : switch ((int) ret) {
568 : case CS_END_RESULTS:
569 : /*
570 : * Everything went fine.
571 : */
572 : break;
573 :
574 2 : case CS_FAIL:
575 : /*
576 : * Something failed happened.
577 : */
578 2 : fprintf(stderr, "ct_results failed.");
579 2 : break;
580 :
581 0 : default:
582 : /*
583 : * We got an unexpected return value.
584 : */
585 0 : fprintf(stderr, "ct_results returned unexpected result type.");
586 0 : break;
587 : }
588 :
589 : return CS_SUCCEED;
590 :
591 :
592 :
593 : }
594 :
595 : static CS_INT
596 212 : ex_display_dlen(CS_DATAFMT *column)
597 : {
598 : CS_INT len;
599 :
600 212 : switch ((int) column->datatype) {
601 164 : case CS_CHAR_TYPE:
602 : case CS_VARCHAR_TYPE:
603 : case CS_TEXT_TYPE:
604 : case CS_IMAGE_TYPE:
605 164 : len = MIN(column->maxlength, 1024);
606 164 : break;
607 :
608 0 : case CS_BINARY_TYPE:
609 : case CS_VARBINARY_TYPE:
610 0 : len = MIN((2 * column->maxlength) + 2, 1024);
611 0 : break;
612 :
613 : case CS_BIT_TYPE:
614 : case CS_TINYINT_TYPE:
615 : len = 3;
616 : break;
617 :
618 8 : case CS_SMALLINT_TYPE:
619 8 : len = 6;
620 8 : break;
621 :
622 8 : case CS_INT_TYPE:
623 8 : len = 11;
624 8 : break;
625 :
626 8 : case CS_REAL_TYPE:
627 : case CS_FLOAT_TYPE:
628 8 : len = 20;
629 8 : break;
630 :
631 8 : case CS_MONEY_TYPE:
632 : case CS_MONEY4_TYPE:
633 8 : len = 24;
634 8 : break;
635 :
636 8 : case CS_DATETIME_TYPE:
637 : case CS_DATETIME4_TYPE:
638 8 : len = 30;
639 8 : break;
640 :
641 0 : case CS_NUMERIC_TYPE:
642 : case CS_DECIMAL_TYPE:
643 0 : len = (CS_MAX_PREC + 2);
644 0 : break;
645 :
646 8 : default:
647 8 : len = 12;
648 8 : break;
649 : }
650 :
651 212 : return MAX((CS_INT) (strlen(column->name) + 1), len);
652 : }
653 :
654 : static CS_RETCODE
655 12 : ex_display_header(CS_INT numcols, CS_DATAFMT columns[])
656 : {
657 : CS_INT i;
658 : CS_INT l;
659 : CS_INT j;
660 : CS_INT disp_len;
661 :
662 12 : fputc('\n', stdout);
663 68 : for (i = 0; i < numcols; i++) {
664 56 : disp_len = ex_display_dlen(&columns[i]);
665 56 : printf("%s", columns[i].name);
666 56 : fflush(stdout);
667 56 : l = disp_len - strlen(columns[i].name);
668 1024 : for (j = 0; j < l; j++) {
669 968 : fputc(' ', stdout);
670 968 : fflush(stdout);
671 : }
672 : }
673 12 : fputc('\n', stdout);
674 12 : fflush(stdout);
675 68 : for (i = 0; i < numcols; i++) {
676 56 : disp_len = ex_display_dlen(&columns[i]);
677 56 : l = disp_len - 1;
678 1224 : for (j = 0; j < l; j++) {
679 1168 : fputc('-', stdout);
680 : }
681 56 : fputc(' ', stdout);
682 : }
683 12 : fputc('\n', stdout);
684 :
685 12 : return CS_SUCCEED;
686 : }
687 :
688 : CS_RETCODE
689 4 : ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg)
690 : {
691 4 : printf("\nOpen Client Message:\n");
692 4 : printf("Message number: LAYER = (%ld) ORIGIN = (%ld) ", (long) CS_LAYER(errmsg->msgnumber), (long) CS_ORIGIN(errmsg->msgnumber));
693 4 : printf("SEVERITY = (%ld) NUMBER = (%ld)\n", (long) CS_SEVERITY(errmsg->msgnumber), (long) CS_NUMBER(errmsg->msgnumber));
694 4 : printf("Message String: %s\n", errmsg->msgstring);
695 4 : if (errmsg->osstringlen > 0) {
696 0 : printf("Operating System Error: %s\n", errmsg->osstring);
697 : }
698 4 : fflush(stdout);
699 :
700 4 : return CS_SUCCEED;
701 : }
702 :
703 : CS_RETCODE
704 12 : ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * srvmsg)
705 : {
706 12 : printf("\nServer message:\n");
707 12 : printf("Message number: %ld, Severity %ld, ", (long) srvmsg->msgnumber, (long) srvmsg->severity);
708 12 : printf("State %ld, Line %ld\n", (long) srvmsg->state, (long) srvmsg->line);
709 :
710 12 : if (srvmsg->svrnlen > 0) {
711 12 : printf("Server '%s'\n", srvmsg->svrname);
712 : }
713 :
714 12 : if (srvmsg->proclen > 0) {
715 4 : printf(" Procedure '%s'\n", srvmsg->proc);
716 : }
717 :
718 12 : printf("Message String: %s\n", srvmsg->text);
719 12 : fflush(stdout);
720 :
721 12 : return CS_SUCCEED;
722 : }
|