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