Line data Source code
1 : #include <config.h>
2 :
3 : #include <stdarg.h>
4 : #include <stdio.h>
5 :
6 : #if HAVE_STDLIB_H
7 : #include <stdlib.h>
8 : #endif /* HAVE_STDLIB_H */
9 :
10 : #if HAVE_STRING_H
11 : #include <string.h>
12 : #endif /* HAVE_STRING_H */
13 :
14 : #include <ctpublic.h>
15 : #include "common.h"
16 :
17 : static CS_RETCODE ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * errmsg);
18 : static CS_RETCODE ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg);
19 :
20 : static int verbose = 0;
21 :
22 : static CS_CONTEXT *ctx;
23 : static CS_CONNECTION *conn;
24 : static CS_COMMAND *cmd;
25 : static CS_COMMAND *cmd2;
26 :
27 : static void
28 8 : cleanup(void)
29 : {
30 : CS_RETCODE ret;
31 :
32 8 : if (verbose) {
33 0 : printf("Trying logout\n");
34 : }
35 :
36 8 : if (cmd2)
37 8 : ct_cmd_drop(cmd2);
38 :
39 8 : ret = try_ctlogout(ctx, conn, cmd, verbose);
40 8 : if (ret != CS_SUCCEED) {
41 0 : fprintf(stderr, "Logout failed\n");
42 0 : exit(1);
43 : }
44 8 : }
45 :
46 : static void
47 442 : chk(int check, const char *fmt, ...)
48 : {
49 : va_list ap;
50 :
51 442 : if (check)
52 442 : return;
53 :
54 0 : va_start(ap, fmt);
55 0 : vfprintf(stderr, fmt, ap);
56 0 : va_end(ap);
57 :
58 0 : cleanup();
59 0 : exit(1);
60 : }
61 :
62 : int
63 8 : main(int argc, char *argv[])
64 : {
65 8 : int errCode = 1;
66 :
67 : CS_RETCODE ret;
68 : CS_RETCODE results_ret;
69 : CS_CHAR cmdbuf[4096];
70 : CS_CHAR name[257];
71 : CS_INT datalength;
72 : CS_SMALLINT ind;
73 : CS_INT count;
74 : CS_INT num_cols;
75 8 : CS_INT row_count = 0;
76 : CS_DATAFMT datafmt;
77 : CS_DATAFMT descfmt;
78 : CS_INT intvar;
79 : CS_INT intvarsize;
80 : CS_SMALLINT intvarind;
81 : CS_INT res_type;
82 :
83 : int i;
84 :
85 8 : if (argc > 1 && (0 == strcmp(argv[1], "-v")))
86 0 : verbose = 1;
87 :
88 8 : printf("%s: use ct_dynamic to prepare and execute a statement\n", __FILE__);
89 8 : if (verbose) {
90 0 : printf("Trying login\n");
91 : }
92 8 : ret = try_ctlogin(&ctx, &conn, &cmd, verbose);
93 8 : if (ret != CS_SUCCEED) {
94 0 : fprintf(stderr, "Login failed\n");
95 0 : return 1;
96 : }
97 :
98 8 : ct_callback(ctx, NULL, CS_SET, CS_CLIENTMSG_CB, (CS_VOID *) ex_clientmsg_cb);
99 :
100 8 : ct_callback(ctx, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID *) ex_servermsg_cb);
101 :
102 8 : ret = ct_cmd_alloc(conn, &cmd2);
103 8 : chk(ret == CS_SUCCEED, "cmd2_alloc failed\n");
104 :
105 : /* do not test error */
106 8 : ret = run_command(cmd, "IF OBJECT_ID('tempdb..#ct_dynamic') IS NOT NULL DROP table #ct_dynamic");
107 :
108 8 : strcpy(cmdbuf, "create table #ct_dynamic (id numeric identity not null, \
109 : name varchar(30), age int, cost money, bdate datetime, fval float) ");
110 :
111 8 : ret = run_command(cmd, cmdbuf);
112 8 : chk(ret == CS_SUCCEED, "create table failed\n");
113 :
114 8 : strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
115 8 : strcat(cmdbuf, "values ('Bill', 44, 2000.00, 'May 21 1960', 60.97 ) ");
116 :
117 8 : ret = run_command(cmd, cmdbuf);
118 8 : chk(ret == CS_SUCCEED, "insert table failed\n");
119 :
120 8 : strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
121 8 : strcat(cmdbuf, "values ('Freddy', 32, 1000.00, 'Jan 21 1972', 70.97 ) ");
122 :
123 8 : ret = run_command(cmd, cmdbuf);
124 8 : chk(ret == CS_SUCCEED, "insert table failed\n");
125 :
126 8 : strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
127 8 : strcat(cmdbuf, "values ('James', 42, 5000.00, 'May 21 1962', 80.97 ) ");
128 :
129 8 : ret = run_command(cmd, cmdbuf);
130 8 : chk(ret == CS_SUCCEED, "insert table failed\n");
131 :
132 8 : strcpy(cmdbuf, "select name from #ct_dynamic where age = ?");
133 :
134 8 : ret = ct_dynamic(cmd, CS_PREPARE, "age", CS_NULLTERM, cmdbuf, CS_NULLTERM);
135 8 : chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
136 :
137 8 : chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_PREPARE) failed\n");
138 :
139 32 : while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
140 16 : switch ((int) res_type) {
141 :
142 : case CS_CMD_SUCCEED:
143 : case CS_CMD_DONE:
144 : break;
145 :
146 : case CS_CMD_FAIL:
147 : break;
148 :
149 : default:
150 : goto ERR;
151 : }
152 : }
153 8 : chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
154 :
155 8 : ret = ct_dynamic(cmd, CS_DESCRIBE_INPUT, "age", CS_NULLTERM, NULL, CS_UNUSED);
156 8 : chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
157 :
158 8 : chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_DESCRIBE_INPUT) failed\n");
159 :
160 32 : while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
161 16 : switch ((int) res_type) {
162 :
163 8 : case CS_DESCRIBE_RESULT:
164 8 : ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
165 8 : chk(ret == CS_SUCCEED, "ct_res_info() failed");
166 :
167 10 : for (i = 1; i <= num_cols; i++) {
168 2 : ret = ct_describe(cmd, i, &descfmt);
169 2 : chk(ret == CS_SUCCEED, "ct_describe() failed");
170 2 : fprintf(stderr, "CS_DESCRIBE_INPUT parameter %d :\n", i);
171 2 : if (descfmt.namelen == 0)
172 2 : fprintf(stderr, "\t\tNo name...\n");
173 : else
174 0 : fprintf(stderr, "\t\tName = %*.*s\n", descfmt.namelen, descfmt.namelen, descfmt.name);
175 2 : fprintf(stderr, "\t\tType = %d\n", descfmt.datatype);
176 2 : fprintf(stderr, "\t\tLength = %d\n", descfmt.maxlength);
177 : }
178 : break;
179 :
180 : case CS_CMD_SUCCEED:
181 : case CS_CMD_DONE:
182 : break;
183 :
184 : case CS_CMD_FAIL:
185 : break;
186 :
187 : default:
188 : goto ERR;
189 : }
190 : }
191 :
192 8 : ret = ct_dynamic(cmd, CS_DESCRIBE_OUTPUT, "age", CS_NULLTERM, NULL, CS_UNUSED);
193 8 : chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
194 :
195 8 : chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_DESCRIBE_OUTPUT) failed\n");
196 :
197 32 : while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
198 16 : switch ((int) res_type) {
199 :
200 8 : case CS_DESCRIBE_RESULT:
201 8 : ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
202 8 : chk(ret == CS_SUCCEED, "ct_res_info() failed");
203 8 : chk(num_cols == 1, "CS_DESCRIBE_OUTPUT showed %d columns , expected 1\n", num_cols);
204 :
205 16 : for (i = 1; i <= num_cols; i++) {
206 8 : ret = ct_describe(cmd, i, &descfmt);
207 8 : chk(ret == CS_SUCCEED, "ct_describe() failed");
208 :
209 8 : if (descfmt.namelen == 0)
210 0 : fprintf(stderr, "\t\tNo name...\n");
211 : else
212 8 : fprintf(stderr, "\t\tName = %*.*s\n", descfmt.namelen, descfmt.namelen, descfmt.name);
213 8 : fprintf(stderr, "\t\tType = %d\n", descfmt.datatype);
214 8 : fprintf(stderr, "\t\tLength = %d\n", descfmt.maxlength);
215 : }
216 : break;
217 :
218 : case CS_CMD_SUCCEED:
219 : case CS_CMD_DONE:
220 : break;
221 :
222 : case CS_CMD_FAIL:
223 : break;
224 :
225 : default:
226 : goto ERR;
227 : }
228 : }
229 :
230 : /* execute dynamic on a second command to check it still works */
231 8 : ret = ct_dynamic(cmd2, CS_EXECUTE, "age", CS_NULLTERM, NULL, CS_UNUSED);
232 8 : chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
233 :
234 8 : intvar = 44;
235 8 : intvarsize = 4;
236 8 : intvarind = 0;
237 :
238 8 : datafmt.name[0] = 0;
239 8 : datafmt.namelen = 0;
240 8 : datafmt.datatype = CS_INT_TYPE;
241 8 : datafmt.status = CS_INPUTVALUE;
242 :
243 8 : ret = ct_setparam(cmd2, &datafmt, (CS_VOID *) & intvar, &intvarsize, &intvarind);
244 8 : chk(ret == CS_SUCCEED, "ct_setparam(int) failed\n");
245 :
246 8 : chk(ct_send(cmd2) == CS_SUCCEED, "ct_send(CS_EXECUTE) failed\n");
247 :
248 8 : while ((results_ret = ct_results(cmd2, &res_type)) == CS_SUCCEED) {
249 32 : chk(res_type != CS_CMD_FAIL, "1: ct_results() result_type CS_CMD_FAIL.\n");
250 32 : chk(res_type != CS_COMPUTE_RESULT, "ct_results() unexpected CS_COMPUTE_RESULT.\n");
251 :
252 32 : switch ((int) res_type) {
253 : case CS_CMD_SUCCEED:
254 : break;
255 : case CS_CMD_DONE:
256 : break;
257 8 : case CS_ROW_RESULT:
258 8 : datafmt.datatype = CS_CHAR_TYPE;
259 8 : datafmt.format = CS_FMT_NULLTERM;
260 8 : datafmt.maxlength = 256;
261 8 : datafmt.count = 1;
262 8 : datafmt.locale = NULL;
263 8 : ret = ct_bind(cmd2, 1, &datafmt, name, &datalength, &ind);
264 8 : chk(ret == CS_SUCCEED, "ct_bind() failed\n");
265 :
266 24 : while (((ret = ct_fetch(cmd2, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
267 8 : || (ret == CS_ROW_FAIL)) {
268 8 : row_count += count;
269 8 : chk(ret != CS_ROW_FAIL, "ct_fetch() CS_ROW_FAIL on row %d.\n", row_count);
270 8 : if (ret == CS_SUCCEED) {
271 8 : chk(!strcmp(name, "Bill"), "fetched value '%s' expected 'Bill'\n", name);
272 : } else {
273 : break;
274 : }
275 : }
276 8 : chk(ret == CS_END_DATA, "ct_fetch() unexpected return %d.\n", (int) ret);
277 8 : break;
278 0 : default:
279 0 : fprintf(stderr, "ct_results() unexpected result_type.\n");
280 0 : return 1;
281 : }
282 : }
283 8 : chk(results_ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) results_ret);
284 :
285 8 : intvar = 32;
286 :
287 8 : chk(ct_send(cmd2) == CS_SUCCEED, "ct_send(CS_EXECUTE) failed\n");
288 :
289 8 : while ((results_ret = ct_results(cmd2, &res_type)) == CS_SUCCEED) {
290 32 : chk(res_type != CS_CMD_FAIL, "2: ct_results() result_type CS_CMD_FAIL.\n");
291 32 : chk(res_type != CS_COMPUTE_RESULT, "ct_results() unexpected CS_COMPUTE_RESULT.\n");
292 :
293 32 : switch ((int) res_type) {
294 : case CS_CMD_SUCCEED:
295 : break;
296 : case CS_CMD_DONE:
297 : break;
298 8 : case CS_ROW_RESULT:
299 8 : datafmt.datatype = CS_CHAR_TYPE;
300 8 : datafmt.format = CS_FMT_NULLTERM;
301 8 : datafmt.maxlength = 256;
302 8 : datafmt.count = 1;
303 8 : datafmt.locale = NULL;
304 8 : ret = ct_bind(cmd2, 1, &datafmt, name, &datalength, &ind);
305 8 : chk(ret == CS_SUCCEED, "ct_bind() failed\n");
306 :
307 24 : while (((ret = ct_fetch(cmd2, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
308 8 : || (ret == CS_ROW_FAIL)) {
309 8 : row_count += count;
310 8 : chk(ret != CS_ROW_FAIL, "ct_fetch() CS_ROW_FAIL on row %d.\n", row_count);
311 :
312 8 : if (ret == CS_SUCCEED) {
313 8 : chk(!strcmp(name, "Freddy"), "fetched value '%s' expected 'Freddy'\n", name);
314 : } else {
315 : break;
316 : }
317 : }
318 8 : chk(ret == CS_END_DATA, "ct_fetch() unexpected return %d.\n", (int) ret);
319 8 : break;
320 0 : default:
321 0 : fprintf(stderr, "ct_results() unexpected result_type.\n");
322 0 : return 1;
323 : }
324 : }
325 8 : chk(results_ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) results_ret);
326 :
327 8 : ret = ct_dynamic(cmd, CS_DEALLOC, "age", CS_NULLTERM, NULL, CS_UNUSED);
328 8 : chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
329 :
330 8 : chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_DEALLOC) failed\n");
331 :
332 20 : while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
333 4 : switch ((int) res_type) {
334 :
335 : case CS_CMD_SUCCEED:
336 : case CS_CMD_DONE:
337 : break;
338 :
339 : case CS_CMD_FAIL:
340 : break;
341 :
342 : default:
343 : goto ERR;
344 : }
345 : }
346 8 : chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
347 :
348 : /*
349 : * check we can prepare again dynamic with same name after deallocation
350 : */
351 8 : strcpy(cmdbuf, "select name from #ct_dynamic where age = ?");
352 8 : ret = ct_dynamic(cmd, CS_PREPARE, "age", CS_NULLTERM, cmdbuf, CS_NULLTERM);
353 8 : chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
354 :
355 8 : chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_PREPARE) failed\n");
356 :
357 32 : while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
358 16 : switch ((int) res_type) {
359 :
360 : case CS_CMD_SUCCEED:
361 : case CS_CMD_DONE:
362 : break;
363 :
364 : case CS_CMD_FAIL:
365 : break;
366 :
367 : default:
368 : goto ERR;
369 : }
370 : }
371 8 : chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
372 :
373 8 : ct_dynamic(cmd, CS_DEALLOC, "invalid", CS_NULLTERM, NULL, CS_UNUSED);
374 8 : ct_send(cmd);
375 16 : while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED)
376 0 : chk(res_type != CS_ROW_RESULT, "Rows not expected\n");
377 8 : chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
378 :
379 8 : ret = ct_dynamic(cmd2, CS_EXECUTE, "age", CS_NULLTERM, NULL, CS_UNUSED);
380 8 : chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
381 :
382 8 : intvar = 32;
383 8 : intvarsize = 4;
384 8 : intvarind = 0;
385 :
386 8 : datafmt.name[0] = 0;
387 8 : datafmt.namelen = 0;
388 8 : datafmt.datatype = CS_INT_TYPE;
389 8 : datafmt.status = CS_INPUTVALUE;
390 :
391 8 : ret = ct_setparam(cmd2, &datafmt, (CS_VOID *) & intvar, &intvarsize, &intvarind);
392 8 : chk(ct_send(cmd2) == CS_SUCCEED, "ct_send(CS_EXECUTE) failed\n");
393 :
394 : /* all tests succeeded */
395 8 : errCode = 0;
396 :
397 8 : ERR:
398 8 : cleanup();
399 8 : return errCode;
400 : }
401 :
402 :
403 : static CS_RETCODE
404 0 : ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg)
405 : {
406 0 : printf("\nOpen Client Message:\n");
407 0 : printf("Message number: LAYER = (%d) ORIGIN = (%d) ", CS_LAYER(errmsg->msgnumber), CS_ORIGIN(errmsg->msgnumber));
408 0 : printf("SEVERITY = (%d) NUMBER = (%d)\n", CS_SEVERITY(errmsg->msgnumber), CS_NUMBER(errmsg->msgnumber));
409 0 : printf("Message String: %s\n", errmsg->msgstring);
410 0 : if (errmsg->osstringlen > 0) {
411 0 : printf("Operating System Error: %s\n", errmsg->osstring);
412 : }
413 0 : fflush(stdout);
414 :
415 0 : return CS_SUCCEED;
416 : }
417 :
418 : static CS_RETCODE
419 0 : ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * srvmsg)
420 : {
421 0 : printf("\nServer message:\n");
422 0 : printf("Message number: %d, Severity %d, ", srvmsg->msgnumber, srvmsg->severity);
423 0 : printf("State %d, Line %d\n", srvmsg->state, srvmsg->line);
424 :
425 0 : if (srvmsg->svrnlen > 0) {
426 0 : printf("Server '%s'\n", srvmsg->svrname);
427 : }
428 :
429 0 : if (srvmsg->proclen > 0) {
430 0 : printf(" Procedure '%s'\n", srvmsg->proc);
431 : }
432 :
433 0 : printf("Message String: %s\n", srvmsg->text);
434 0 : fflush(stdout);
435 :
436 0 : return CS_SUCCEED;
437 : }
|