1 #include <config.h>
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <ctpublic.h>
6 #include "common.h"
7
8 static int sp_who(CS_COMMAND *cmd);
9
10 /*
11 * ct_send SQL |select name = @@servername|
12 * ct_bind variable
13 * ct_fetch and print results
14 */
15 int
main(int argc,char ** argv)16 main(int argc, char **argv)
17 {
18 CS_CONTEXT *ctx;
19 CS_CONNECTION *conn;
20 CS_COMMAND *cmd;
21 int verbose = 0;
22
23 CS_RETCODE ret;
24 CS_RETCODE results_ret;
25 CS_DATAFMT datafmt;
26 CS_INT datalength;
27 CS_SMALLINT ind;
28 CS_INT count, row_count = 0;
29 CS_INT result_type;
30 CS_CHAR name[256];
31
32 printf("%s: Testing bind & select\n", __FILE__);
33 if (verbose) {
34 printf("Trying login\n");
35 }
36 ret = try_ctlogin(&ctx, &conn, &cmd, verbose);
37 if (ret != CS_SUCCEED) {
38 fprintf(stderr, "Login failed\n");
39 return 1;
40 }
41
42 ret = ct_command(cmd, CS_LANG_CMD, "select name = @@servername", CS_NULLTERM, CS_UNUSED);
43 if (ret != CS_SUCCEED) {
44 fprintf(stderr, "ct_command() failed\n");
45 return 1;
46 }
47 ret = ct_send(cmd);
48 if (ret != CS_SUCCEED) {
49 fprintf(stderr, "ct_send() failed\n");
50 return 1;
51 }
52 while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED) {
53 switch ((int) result_type) {
54 case CS_CMD_SUCCEED:
55 break;
56 case CS_CMD_DONE:
57 break;
58 case CS_CMD_FAIL:
59 fprintf(stderr, "ct_results() result_type CS_CMD_FAIL.\n");
60 return 1;
61 case CS_ROW_RESULT:
62 datafmt.datatype = CS_CHAR_TYPE;
63 datafmt.format = CS_FMT_NULLTERM;
64 datafmt.maxlength = 256;
65 datafmt.count = 1;
66 datafmt.locale = NULL;
67 ret = ct_bind(cmd, 1, &datafmt, name, &datalength, &ind);
68 if (ret != CS_SUCCEED) {
69 fprintf(stderr, "ct_bind() failed\n");
70 return 1;
71 }
72
73 while (((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
74 || (ret == CS_ROW_FAIL)) {
75 row_count += count;
76 if (ret == CS_ROW_FAIL) {
77 fprintf(stderr, "ct_fetch() CS_ROW_FAIL on row %d.\n", row_count);
78 return 1;
79 } else if (ret == CS_SUCCEED) {
80 if (verbose) {
81 printf("server name = %s\n", name);
82 }
83 } else {
84 break;
85 }
86 }
87 switch ((int) ret) {
88 case CS_END_DATA:
89 break;
90 case CS_FAIL:
91 fprintf(stderr, "ct_fetch() returned CS_FAIL.\n");
92 return 1;
93 default:
94 fprintf(stderr, "ct_fetch() unexpected return.\n");
95 return 1;
96 }
97 break;
98 case CS_COMPUTE_RESULT:
99 fprintf(stderr, "ct_results() unexpected CS_COMPUTE_RESULT.\n");
100 return 1;
101 default:
102 fprintf(stderr, "ct_results() unexpected result_type.\n");
103 return 1;
104 }
105 }
106 switch ((int) results_ret) {
107 case CS_END_RESULTS:
108 break;
109 case CS_FAIL:
110 fprintf(stderr, "ct_results() failed.\n");
111 return 1;
112 break;
113 default:
114 fprintf(stderr, "ct_results() unexpected return.\n");
115 return 1;
116 }
117
118 /*
119 * test parameter return code processing with sp_who
120 */
121 sp_who(cmd);
122
123 if (verbose) {
124 printf("Trying logout\n");
125 }
126 ret = try_ctlogout(ctx, conn, cmd, verbose);
127 if (ret != CS_SUCCEED) {
128 fprintf(stderr, "Logout failed\n");
129 return 1;
130 }
131
132 return 0;
133 }
134
135 int
sp_who(CS_COMMAND * cmd)136 sp_who(CS_COMMAND *cmd)
137 {
138 enum {maxcol=10, colsize=260};
139
140 struct _col {
141 CS_DATAFMT datafmt;
142 CS_INT datalength;
143 CS_SMALLINT ind;
144 CS_CHAR data[colsize];
145 } col[maxcol];
146
147 CS_INT num_cols;
148 CS_INT count, row_count = 0;
149 CS_INT result_type;
150 CS_RETCODE ret;
151 CS_RETCODE results_ret;
152 int i;
153 int is_status_result=0;
154
155 ret = ct_command(cmd, CS_LANG_CMD, "exec sp_who", CS_NULLTERM, CS_UNUSED);
156 if (ret != CS_SUCCEED) {
157 fprintf(stderr, "ct_command: \"exec sp_who\" failed with %d\n", ret);
158 return 1;
159 }
160 ret = ct_send(cmd);
161 if (ret != CS_SUCCEED) {
162 fprintf(stderr, "ct_send: \"exec sp_who\" failed with %d\n", ret);
163 return 1;
164 }
165 while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED) {
166 is_status_result = 0;
167 switch ((int) result_type) {
168 case CS_CMD_SUCCEED:
169 break;
170 case CS_CMD_DONE:
171 break;
172 case CS_CMD_FAIL:
173 fprintf(stderr, "ct_results() result_type CS_CMD_FAIL.\n");
174 return 1;
175 case CS_STATUS_RESULT:
176 printf("ct_results: CS_STATUS_RESULT detected for sp_who\n");
177 is_status_result = 1;
178 /* fall through */
179 case CS_ROW_RESULT:
180 ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
181 if (ret != CS_SUCCEED || num_cols > maxcol) {
182 fprintf(stderr, "ct_res_info() failed\n");
183 return 1;
184 }
185
186 if (num_cols <= 0) {
187 fprintf(stderr, "ct_res_info() return strange values\n");
188 return 1;
189 }
190
191 if (is_status_result && num_cols != 1) {
192 fprintf(stderr, "CS_STATUS_RESULT return more than 1 column\n");
193 return 1;
194 }
195
196 for (i=0; i < num_cols; i++) {
197
198 /* here we can finally test for the return status column */
199 ret = ct_describe(cmd, i+1, &col[i].datafmt);
200
201 if (ret != CS_SUCCEED) {
202 fprintf(stderr, "ct_describe() failed for column %d\n", i);
203 return 1;
204 }
205
206 if (col[i].datafmt.status & CS_RETURN) {
207 printf("ct_describe() indicates a return code in column %d for sp_who\n", i);
208
209 /*
210 * other possible values:
211 * CS_CANBENULL
212 * CS_HIDDEN
213 * CS_IDENTITY
214 * CS_KEY
215 * CS_VERSION_KEY
216 * CS_TIMESTAMP
217 * CS_UPDATABLE
218 * CS_UPDATECOL
219 */
220 }
221
222 col[i].datafmt.datatype = CS_CHAR_TYPE;
223 col[i].datafmt.format = CS_FMT_NULLTERM;
224 col[i].datafmt.maxlength = colsize;
225 col[i].datafmt.count = 1;
226 col[i].datafmt.locale = NULL;
227
228 ret = ct_bind(cmd, i+1, &col[i].datafmt, &col[i].data, &col[i].datalength, &col[i].ind);
229 if (ret != CS_SUCCEED) {
230 fprintf(stderr, "ct_bind() failed\n");
231 return 1;
232 }
233
234 }
235
236 row_count = 0;
237 while ((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED) {
238 if( row_count == 0) { /* titles */
239 for (i=0; i < num_cols; i++) {
240 char fmt[40];
241 if (col[i].datafmt.namelen == 0) {
242 printf("unnamed%d ",i+1);
243 continue;
244 }
245 sprintf(fmt, "%%-%d.%ds ", col[i].datafmt.namelen, col[i].datafmt.maxlength);
246 printf(fmt, col[i].datafmt.name);
247 }
248 printf("\n");
249 }
250
251 for (i=0; i < num_cols; i++) { /* data */
252 char fmt[40];
253 if (col[i].ind)
254 continue;
255 sprintf(fmt, "%%-%d.%ds ", col[i].datalength, col[i].datafmt.maxlength);
256 printf(fmt, col[i].data);
257 if (is_status_result && strcmp(col[i].data,"0")) {
258 fprintf(stderr, "CS_STATUS_RESULT should return 0 as result\n");
259 return 1;
260 }
261 }
262
263 printf("\n");
264
265 row_count += count;
266 }
267 if (is_status_result && row_count != 1) {
268 fprintf(stderr, "CS_STATUS_RESULT should return a row\n");
269 return 1;
270 }
271
272 switch ((int) ret) {
273 case CS_END_DATA:
274 printf("ct_results fetched %d rows.\n", row_count);
275 break;
276 case CS_ROW_FAIL:
277 fprintf(stderr, "ct_fetch() CS_ROW_FAIL on row %d.\n", row_count);
278 return 1;
279 case CS_FAIL:
280 fprintf(stderr, "ct_fetch() returned CS_FAIL.\n");
281 return 1;
282 default:
283 fprintf(stderr, "ct_fetch() unexpected return.\n");
284 return 1;
285 }
286 break;
287 case CS_COMPUTE_RESULT:
288 fprintf(stderr, "ct_results() unexpected CS_COMPUTE_RESULT.\n");
289 return 1;
290 default:
291 fprintf(stderr, "ct_results() unexpected result_type.\n");
292 return 1;
293 }
294 }
295
296 switch ((int) results_ret) {
297 case CS_END_RESULTS:
298 break;
299 case CS_FAIL:
300 fprintf(stderr, "ct_results() failed.\n");
301 return 1;
302 break;
303 default:
304 fprintf(stderr, "ct_results() unexpected return.\n");
305 return 1;
306 }
307
308 return 0;
309 }
310