NCBI C++ ToolKit
ct_dynamic.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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