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

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

1 /*
2  * Tests rows count
3  *
4  * These are the results using Sybase CT-Library. This test check that ct_results returns the same results.
5  *
6  *
7  * "insert into #tmp1 values(1) "
8  * "insert into #tmp1 values(2) "
9  * "insert into #tmp1 values(3) "
10  * "select * from #tmp1 "
11  *
12  * Open Client Message:
13  * number 16843050 layer 1 origin 1 severity 1 number 42
14  * msgstring: ct_res_info(ROWCOUNT): user api layer: external error: This routine cannot be called after ct_results() returns a result type of CS_ROW_RESULT.
15  * osstring: (null)
16  * ct_results returned CS_ROW_RESULT type and -1 rows
17  * All done processing rows.
18  * ct_results returned CS_CMD_DONE type and 3 rows
19  *
20  * Open Client Message:
21  * number 16843051 layer 1 origin 1 severity 1 number 43
22  * msgstring: ct_res_info(ROWCOUNT): user api layer: external error: This routine cannot be called after ct_results() returns a result type of CS_STATUS_RESULT.
23  * osstring: (null)
24  * ct_results returned CS_STATUS_RESULT type and -1 rows
25  * All done processing rows.
26  * ct_results returned CS_CMD_SUCCEED type and -1 rows
27  * ct_results returned CS_CMD_DONE type and -1 rows
28  *
29  *
30  * "insert into #tmp1 values(1) "
31  * "insert into #tmp1 values(2) "
32  * "insert into #tmp1 values(3) "
33  * "select * from #tmp1 "
34  * "insert into #tmp1 values(4) "
35  * "delete from #tmp1 where i <= 2 "
36  *
37  * Open Client Message:
38  * number 16843050 layer 1 origin 1 severity 1 number 42
39  * msgstring: ct_res_info(ROWCOUNT): user api layer: external error: This routine cannot be called after ct_results() returns a result type of CS_ROW_RESULT.
40  * osstring: (null)
41  * ct_results returned CS_ROW_RESULT type and -1 rows
42  * All done processing rows.
43  * ct_results returned CS_CMD_DONE type and 3 rows
44  *
45  * Open Client Message:
46  * number 16843051 layer 1 origin 1 severity 1 number 43
47  * msgstring: ct_res_info(ROWCOUNT): user api layer: external error: This routine cannot be called after ct_results() returns a result type of CS_STATUS_RESULT.
48  * osstring: (null)
49  * ct_results returned CS_STATUS_RESULT type and -1 rows
50  * All done processing rows.
51  * ct_results returned CS_CMD_SUCCEED type and 2 rows
52  * ct_results returned CS_CMD_DONE type and 2 rows
53  */
54 
55 #undef NDEBUG
56 #include <config.h>
57 
58 #include <stdio.h>
59 
60 #if HAVE_STDLIB_H
61 #include <stdlib.h>
62 #endif /* HAVE_STDLIB_H */
63 
64 #if HAVE_STRING_H
65 #include <string.h>
66 #endif /* HAVE_STRING_H */
67 
68 #include <ctpublic.h>
69 #include "common.h"
70 #include "replacements.h"
71 
72 #include <common/test_assert.h>
73 
74 static CS_CONTEXT *ctx;
76 static CS_COMMAND *cmd;
77 
78 static CS_RETCODE ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg);
79 static CS_RETCODE ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * errmsg);
80 static CS_INT ex_display_results(CS_COMMAND * cmd, char *results);
81 
82 static int test(int final_rows, int no_rows);
83 
84 int
85 main(int argc, char *argv[])
86 {
87  CS_RETCODE ret;
88 
89  printf("%s: check row count returned\n", __FILE__);
90  ret = try_ctlogin(&ctx, &conn, &cmd, 0);
91  if (ret != CS_SUCCEED) {
92  fprintf(stderr, "Login failed\n");
93  return 1;
94  }
95 
98 
99  /* do not test error */
100  run_command(cmd, "DROP PROCEDURE sample_rpc");
101  run_command(cmd, "drop table #tmp1");
102 
103  /* test with rows from select */
104  if (test(0, 0) || test(1, 0))
105  return 1;
106 
107  /* test with empty select */
108  if (test(0, 1) || test(1, 1))
109  return 1;
110 
111  ret = try_ctlogout(ctx, conn, cmd, 0);
112  if (ret != CS_SUCCEED) {
113  fprintf(stderr, "Logout failed\n");
114  return 1;
115  }
116 
117  return 0;
118 }
119 
120 static int
121 test(int final_rows, int no_rows)
122 {
123  CS_RETCODE ret;
124  CS_CHAR cmdbuf[4096];
125  char results[1024];
126  char *results_end = results, *cmdbuf_end = cmdbuf;
127 
128  run_command(cmd, "create table #tmp1 (i int not null)");
129 
130 #ifdef strcat
131 # undef strcat
132 #endif
133 #define strcat(s, k) do { \
134  memcpy(s##_end, k, sizeof(k)); \
135  s##_end += sizeof(k) - 1; \
136  } while (0)
137 
138  strcat(cmdbuf, "create proc sample_rpc as ");
139 
140  strcat(results, "CS_ROW_RESULT -1\n");
141  strcat(cmdbuf, "insert into #tmp1 values(1) "
142  "insert into #tmp1 values(2) "
143  "insert into #tmp1 values(3) "
144  );
145 
146  if (no_rows) {
147  strcat(cmdbuf, "select * from #tmp1 where i > 10 ");
148  strcat(results, "CS_CMD_DONE 0\n");
149  } else {
150  strcat(cmdbuf, "select * from #tmp1 ");
151  strcat(results, "CS_CMD_DONE 3\n");
152  }
153 
154  strcat(results, "CS_STATUS_RESULT -1\n");
155 
156  if (final_rows) {
157  strcat(cmdbuf, "insert into #tmp1 values(4) "
158  "delete from #tmp1 where i <= 2 "
159  );
160  strcat(results, "CS_CMD_SUCCEED 2\n"
161  "CS_CMD_DONE 2\n");
162  } else {
163  strcat(results, "CS_CMD_SUCCEED -1\n"
164  "CS_CMD_DONE -1\n");
165  }
166 #undef strcat
167 
168  printf("testing query:\n----\n%s\n----\n", cmdbuf);
169 
170  ret = run_command(cmd, cmdbuf);
171  if (ret != CS_SUCCEED) {
172  fprintf(stderr, "create proc failed\n");
173  return 1;
174  }
175 
176  printf("----------\n");
177  if ((ret = ct_command(cmd, CS_RPC_CMD, "sample_rpc", CS_NULLTERM, CS_NO_RECOMPILE)) != CS_SUCCEED) {
178  fprintf(stderr, "ct_command(CS_RPC_CMD) failed");
179  return 1;
180  }
181 
182  if (ct_send(cmd) != CS_SUCCEED) {
183  fprintf(stderr, "ct_send(RPC) failed");
184  return 1;
185  }
186  ex_display_results(cmd, results);
187 
188  /* cleanup */
189  run_command(cmd, "DROP PROCEDURE sample_rpc");
190  run_command(cmd, "drop table #tmp1");
191 
192  return 0;
193 }
194 
195 static CS_INT
197 {
198  CS_RETCODE ret;
199  CS_INT res_type;
200  CS_INT num_cols;
201  CS_INT row_count = 0;
202  CS_INT rows_read;
203  CS_SMALLINT msg_id;
204 
205  /*
206  * Process the results of the RPC.
207  */
208  while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
209  char res[32];
210  int rows, pos;
211 
212  CS_INT rowsAffected = -1;
213  ct_res_info(cmd, CS_ROW_COUNT, &rowsAffected, CS_UNUSED, NULL);
214  printf("ct_results returned %s type and %d rows\n", res_type_str(res_type), (int) rowsAffected);
215 
216  /* check expected results are the same as got ones */
217  pos = -1;
218  assert(sscanf(results, "%30s %d %n", res, &rows, &pos) >= 2 && pos > 0);
219  results += pos;
220  if (strcmp(res_type_str(res_type), res) != 0 || rowsAffected != rows) {
221  fprintf(stderr, "Expected ct_results %s rows %d\n", res, rows);
222  exit(1);
223  }
224 
225  switch (res_type) {
226  case CS_ROW_RESULT:
227  case CS_PARAM_RESULT:
228  case CS_STATUS_RESULT:
229 
230  /*
231  * All three of these result types are fetchable.
232  * Since the result model for rpcs and rows have
233  * been unified in the New Client-Library, we
234  * will use the same routine to display them
235  */
236 
237  /*
238  * Find out how many columns there are in this result set.
239  */
240  ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
241  if (ret != CS_SUCCEED) {
242  fprintf(stderr, "ct_res_info(CS_NUMDATA) failed");
243  return 1;
244  }
245 
246  /*
247  * Make sure we have at least one column
248  */
249  if (num_cols <= 0) {
250  fprintf(stderr, "ct_res_info(CS_NUMDATA) returned zero columns");
251  return 1;
252  }
253 
254  while (((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
255  &rows_read)) == CS_SUCCEED) || (ret == CS_ROW_FAIL)) {
256  /*
257  * Increment our row count by the number of rows just fetched.
258  */
259  row_count = row_count + rows_read;
260 
261  /*
262  * Check if we hit a recoverable error.
263  */
264  if (ret == CS_ROW_FAIL) {
265  fprintf(stdout, "Error on row %d.\n", row_count);
266  fflush(stdout);
267  }
268  }
269 
270  /*
271  * We're done processing rows. Let's check the final return
272  * value of ct_fetch().
273  */
274  switch ((int) ret) {
275  case CS_END_DATA:
276  /*
277  * Everything went fine.
278  */
279  printf("All done processing rows.\n");
280  fflush(stdout);
281  break;
282 
283  case CS_FAIL:
284  /*
285  * Something terrible happened.
286  */
287  fprintf(stderr, "ct_fetch returned CS_FAIL\n");
288  return 1;
289  break;
290 
291  default:
292  /*
293  * We got an unexpected return value.
294  */
295  fprintf(stderr, "ct_fetch returned %d\n", ret);
296  return 1;
297  break;
298 
299  }
300  break;
301 
302  case CS_MSG_RESULT:
303  ret = ct_res_info(cmd, CS_MSGTYPE, (CS_VOID *) & msg_id, CS_UNUSED, NULL);
304  if (ret != CS_SUCCEED) {
305  fprintf(stderr, "ct_res_info(msg_id) failed");
306  return 1;
307  }
308  printf("ct_result returned CS_MSG_RESULT where msg id = %d.\n", msg_id);
309  fflush(stdout);
310  break;
311 
312  case CS_CMD_SUCCEED:
313  case CS_CMD_DONE:
314  case CS_CMD_FAIL:
315  break;
316 
317  default:
318  /*
319  * We got something unexpected.
320  */
321  fprintf(stderr, "ct_results returned unexpected result type.");
322  return CS_FAIL;
323  }
324  }
325 
326  /*
327  * We're done processing results. Let's check the
328  * return value of ct_results() to see if everything
329  * went ok.
330  */
331  switch ((int) ret) {
332  case CS_END_RESULTS:
333  /*
334  * Everything went fine.
335  */
336  break;
337 
338  case CS_FAIL:
339  /*
340  * Something failed happened.
341  */
342  fprintf(stderr, "ct_results failed.");
343  break;
344 
345  default:
346  /*
347  * We got an unexpected return value.
348  */
349  fprintf(stderr, "ct_results returned unexpected result type.");
350  break;
351  }
352 
353  return CS_SUCCEED;
354 }
355 
356 static CS_RETCODE
357 ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg)
358 {
359  printf("\nOpen Client Message:\n");
360  printf("Message number: LAYER = (%ld) ORIGIN = (%ld) ", (long) CS_LAYER(errmsg->msgnumber), (long) CS_ORIGIN(errmsg->msgnumber));
361  printf("SEVERITY = (%ld) NUMBER = (%ld)\n", (long) CS_SEVERITY(errmsg->msgnumber), (long) CS_NUMBER(errmsg->msgnumber));
362  printf("Message String: %s\n", errmsg->msgstring);
363  if (errmsg->osstringlen > 0) {
364  printf("Operating System Error: %s\n", errmsg->osstring);
365  }
366  fflush(stdout);
367 
368  return CS_SUCCEED;
369 }
370 
371 static CS_RETCODE
372 ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * srvmsg)
373 {
374  printf("\nServer message:\n");
375  printf("Message number: %ld, Severity %ld, ", (long) srvmsg->msgnumber, (long) srvmsg->severity);
376  printf("State %ld, Line %ld\n", (long) srvmsg->state, (long) srvmsg->line);
377 
378  if (srvmsg->svrnlen > 0) {
379  printf("Server '%s'\n", srvmsg->svrname);
380  }
381 
382  if (srvmsg->proclen > 0) {
383  printf(" Procedure '%s'\n", srvmsg->proc);
384  }
385 
386  printf("Message String: %s\n", srvmsg->text);
387  fflush(stdout);
388 
389  return CS_SUCCEED;
390 }
#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_FAIL
Definition: cspublic.h:41
#define CS_PARAM_RESULT
Definition: cspublic.h:540
#define CS_MSGTYPE
Definition: cspublic.h:474
#define CS_MSG_RESULT
Definition: cspublic.h:545
#define CS_RPC_CMD
Definition: cspublic.h:442
#define CS_NUMBER(x)
Definition: cspublic.h:66
#define CS_STATUS_RESULT
Definition: cspublic.h:542
#define CS_LAYER(x)
Definition: cspublic.h:63
#define CS_UNUSED
Definition: cspublic.h:425
#define CS_ROW_COUNT
Definition: cspublic.h:469
#define CS_END_DATA
Definition: cspublic.h:55
#define CS_SET
Definition: cspublic.h:429
#define CS_ROW_RESULT
Definition: cspublic.h:541
#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
@ CS_NO_RECOMPILE
Definition: cspublic.h:383
#define CS_NULLTERM
Definition: cspublic.h:422
#define CS_ORIGIN(x)
Definition: cspublic.h:64
#define CS_END_RESULTS
Definition: cspublic.h:56
#define CS_NUMDATA
Definition: cspublic.h:472
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
const char * res_type_str(CS_RETCODE ret)
Definition: common.c:432
CS_RETCODE try_ctlogout(CS_CONTEXT *ctx, CS_CONNECTION *conn, CS_COMMAND *cmd, int verbose)
Definition: common.c:308
CS_RETCODE ct_command(CS_COMMAND *cmd, CS_INT type, const CS_VOID *buffer, CS_INT buflen, CS_INT option)
Definition: ct.c:760
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_send(CS_COMMAND *cmd)
Definition: ct.c:913
#define NULL
Definition: ncbistd.hpp:225
exit(2)
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
static CS_RETCODE ex_clientmsg_cb(CS_CONTEXT *context, CS_CONNECTION *connection, CS_CLIENTMSG *errmsg)
Definition: row_count.c:357
int main(int argc, char *argv[])
Definition: row_count.c:85
static CS_COMMAND * cmd
Definition: row_count.c:76
static CS_CONTEXT * ctx
Definition: row_count.c:74
static CS_RETCODE ex_servermsg_cb(CS_CONTEXT *context, CS_CONNECTION *connection, CS_SERVERMSG *errmsg)
Definition: row_count.c:372
#define strcat(s, k)
static CS_CONNECTION * conn
Definition: row_count.c:75
static int test(int final_rows, int no_rows)
Definition: row_count.c:121
static CS_INT ex_display_results(CS_COMMAND *cmd, char *results)
Definition: row_count.c:196
#define assert(x)
Definition: srv_diag.hpp:58
CS_CHAR osstring[1024]
Definition: cstypes.h:191
CS_MSGNUM msgnumber
Definition: cstypes.h:187
CS_CHAR msgstring[1024]
Definition: cstypes.h:188
CS_INT osstringlen
Definition: cstypes.h:192
CS_CHAR proc[132]
Definition: cstypes.h:207
CS_CHAR text[1024]
Definition: cstypes.h:203
CS_MSGNUM msgnumber
Definition: cstypes.h:200
CS_INT line
Definition: cstypes.h:209
CS_INT svrnlen
Definition: cstypes.h:206
CS_CHAR svrname[132]
Definition: cstypes.h:205
CS_INT severity
Definition: cstypes.h:202
CS_INT proclen
Definition: cstypes.h:208
CS_INT state
Definition: cstypes.h:201
Modified on Tue Apr 09 07:58:35 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 10 07:33:56 2024 by modify_doxy.py rev. 669887
Modified on Thu Apr 11 15:10:27 2024 by modify_doxy.py rev. 669887
Modified on Fri Apr 12 17:19:52 2024 by modify_doxy.py rev. 669887
Modified on Sat Apr 13 11:47:36 2024 by modify_doxy.py rev. 669887
Modified on Sun Apr 14 05:27:32 2024 by modify_doxy.py rev. 669887
Modified on Tue Apr 16 20:11:45 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 17 13:09:50 2024 by modify_doxy.py rev. 669887
Modified on Sat Apr 20 12:19:10 2024 by modify_doxy.py rev. 669887