LCOV - code coverage report
Current view: top level - src/ctlib/unittests - ct_dynamic.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 140 167 83.8 %
Date: 2025-02-21 09:36:06 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : 
       3             : #include <stdarg.h>
       4             : 
       5             : static int verbose = 0;
       6             : 
       7             : static CS_CONTEXT *ctx;
       8             : static CS_CONNECTION *conn;
       9             : static CS_COMMAND *cmd;
      10             : static CS_COMMAND *cmd2;
      11             : 
      12             : static void
      13          10 : cleanup(void)
      14             : {
      15          10 :         if (verbose) {
      16           0 :                 printf("Trying logout\n");
      17             :         }
      18             : 
      19          10 :         if (cmd2)
      20          10 :                 ct_cmd_drop(cmd2);
      21             : 
      22          10 :         check_call(try_ctlogout, (ctx, conn, cmd, verbose));
      23          10 : }
      24             : 
      25             : static void
      26         290 : chk(int check, const char *fmt, ...)
      27             : {
      28             :         va_list ap;
      29             : 
      30         290 :         if (check)
      31         290 :                 return;
      32             : 
      33           0 :         va_start(ap, fmt);
      34           0 :         vfprintf(stderr, fmt, ap);
      35           0 :         va_end(ap);
      36             : 
      37           0 :         cleanup();
      38           0 :         exit(1);
      39             : }
      40             : 
      41             : int
      42          10 : main(int argc, char *argv[])
      43             : {
      44             :         CS_RETCODE ret;
      45             :         CS_RETCODE results_ret;
      46             :         CS_CHAR cmdbuf[4096];
      47             :         CS_CHAR name[257];
      48             :         CS_INT datalength;
      49             :         CS_SMALLINT ind;
      50             :         CS_INT count;
      51             :         CS_INT num_cols;
      52          10 :         CS_INT row_count = 0;
      53             :         CS_DATAFMT datafmt;
      54             :         CS_DATAFMT descfmt;
      55             :         CS_INT intvar;
      56             :         CS_INT intvarsize;
      57             :         CS_SMALLINT intvarind;
      58             :         CS_INT res_type;
      59             : 
      60             :         int i;
      61             : 
      62          10 :         if (argc > 1 && (0 == strcmp(argv[1], "-v")))
      63           0 :                 verbose = 1;
      64             : 
      65          10 :         printf("%s: use ct_dynamic to prepare and execute  a statement\n", __FILE__);
      66          10 :         if (verbose) {
      67           0 :                 printf("Trying login\n");
      68             :         }
      69          10 :         check_call(try_ctlogin, (&ctx, &conn, &cmd, verbose));
      70          10 :         error_to_stdout = true;
      71             : 
      72          10 :         check_call(ct_cmd_alloc, (conn, &cmd2));
      73             : 
      74             :         /* do not test error */
      75          10 :         run_command(cmd, "IF OBJECT_ID('tempdb..#ct_dynamic') IS NOT NULL DROP table #ct_dynamic");
      76             : 
      77          10 :         strcpy(cmdbuf, "create table #ct_dynamic (id numeric identity not null, \
      78             :         name varchar(30), age int, cost money, bdate datetime, fval float) ");
      79             : 
      80          10 :         check_call(run_command, (cmd, cmdbuf));
      81             : 
      82          10 :         strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
      83          10 :         strcat(cmdbuf, "values ('Bill', 44, 2000.00, 'May 21 1960', 60.97 ) ");
      84             : 
      85          10 :         check_call(run_command, (cmd, cmdbuf));
      86             : 
      87          10 :         strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
      88          10 :         strcat(cmdbuf, "values ('Freddy', 32, 1000.00, 'Jan 21 1972', 70.97 ) ");
      89             : 
      90          10 :         check_call(run_command, (cmd, cmdbuf));
      91             : 
      92          10 :         strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
      93          10 :         strcat(cmdbuf, "values ('James', 42, 5000.00, 'May 21 1962', 80.97 ) ");
      94             : 
      95          10 :         check_call(run_command, (cmd, cmdbuf));
      96             : 
      97          10 :         strcpy(cmdbuf, "select name from #ct_dynamic where age = ?");
      98             : 
      99          10 :         check_call(ct_dynamic, (cmd, CS_PREPARE, "age", CS_NULLTERM, cmdbuf, CS_NULLTERM));
     100             : 
     101          10 :         check_call(ct_send, (cmd));
     102             : 
     103          40 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
     104          20 :                 switch ((int) res_type) {
     105             : 
     106             :                 case CS_CMD_SUCCEED:
     107             :                 case CS_CMD_DONE:
     108             :                         break;
     109             : 
     110             :                 case CS_CMD_FAIL:
     111             :                         break;
     112             : 
     113           0 :                 default:
     114           0 :                         chk(0, "invalid ct_results result type: %d\n", res_type);
     115             :                 }
     116             :         }
     117          10 :         chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
     118             : 
     119          10 :         check_call(ct_dynamic, (cmd, CS_DESCRIBE_INPUT, "age", CS_NULLTERM, NULL, CS_UNUSED));
     120             : 
     121          10 :         check_call(ct_send, (cmd));
     122             : 
     123          40 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
     124          20 :                 switch ((int) res_type) {
     125             : 
     126          10 :                 case CS_DESCRIBE_RESULT:
     127          10 :                         check_call(ct_res_info, (cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL));
     128             : 
     129          12 :                         for (i = 1; i <= num_cols; i++) {
     130           2 :                                 check_call(ct_describe, (cmd, i, &descfmt));
     131           2 :                                 fprintf(stderr, "CS_DESCRIBE_INPUT parameter %d :\n", i);
     132           2 :                                 if (descfmt.namelen == 0)
     133           2 :                                         fprintf(stderr, "\t\tNo name...\n");
     134             :                                 else
     135           0 :                                         fprintf(stderr, "\t\tName = %*.*s\n", descfmt.namelen, descfmt.namelen, descfmt.name);
     136           2 :                                 fprintf(stderr, "\t\tType   = %d\n", descfmt.datatype);
     137           2 :                                 fprintf(stderr, "\t\tLength = %d\n", descfmt.maxlength);
     138             :                         }
     139             :                         break;
     140             : 
     141             :                 case CS_CMD_SUCCEED:
     142             :                 case CS_CMD_DONE:
     143             :                         break;
     144             : 
     145             :                 case CS_CMD_FAIL:
     146             :                         break;
     147             : 
     148           0 :                 default:
     149           0 :                         chk(0, "invalid ct_results result type: %d\n", res_type);
     150             :                 }
     151             :         }
     152             : 
     153          10 :         check_call(ct_dynamic, (cmd, CS_DESCRIBE_OUTPUT, "age", CS_NULLTERM, NULL, CS_UNUSED));
     154             : 
     155          10 :         check_call(ct_send, (cmd));
     156             : 
     157          40 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
     158          20 :                 switch ((int) res_type) {
     159             : 
     160          10 :                 case CS_DESCRIBE_RESULT:
     161          10 :                         check_call(ct_res_info, (cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL));
     162          10 :                         chk(num_cols == 1, "CS_DESCRIBE_OUTPUT showed %d columns , expected 1\n", num_cols);
     163             : 
     164          20 :                         for (i = 1; i <= num_cols; i++) {
     165          10 :                                 check_call(ct_describe, (cmd, i, &descfmt));
     166             : 
     167          10 :                                 if (descfmt.namelen == 0)
     168           0 :                                         fprintf(stderr, "\t\tNo name...\n");
     169             :                                 else
     170          10 :                                         fprintf(stderr, "\t\tName = %*.*s\n", descfmt.namelen, descfmt.namelen, descfmt.name);
     171          10 :                                 fprintf(stderr, "\t\tType   = %d\n", descfmt.datatype);
     172          10 :                                 fprintf(stderr, "\t\tLength = %d\n", descfmt.maxlength);
     173             :                         }
     174             :                         break;
     175             : 
     176             :                 case CS_CMD_SUCCEED:
     177             :                 case CS_CMD_DONE:
     178             :                         break;
     179             : 
     180             :                 case CS_CMD_FAIL:
     181             :                         break;
     182             : 
     183           0 :                 default:
     184           0 :                         chk(0, "invalid ct_results result type: %d\n", res_type);
     185             :                 }
     186             :         }
     187             : 
     188             :         /* execute dynamic on a second command to check it still works */
     189          10 :         check_call(ct_dynamic, (cmd2, CS_EXECUTE, "age", CS_NULLTERM, NULL, CS_UNUSED));
     190             : 
     191          10 :         intvar = 44;
     192          10 :         intvarsize = 4;
     193          10 :         intvarind = 0;
     194             : 
     195          10 :         datafmt.name[0] = 0;
     196          10 :         datafmt.namelen = 0;
     197          10 :         datafmt.datatype = CS_INT_TYPE;
     198          10 :         datafmt.status = CS_INPUTVALUE;
     199             : 
     200          10 :         check_call(ct_setparam, (cmd2, &datafmt, (CS_VOID *) & intvar, &intvarsize, &intvarind));
     201             : 
     202          10 :         check_call(ct_send, (cmd2));
     203             : 
     204          10 :         while ((results_ret = ct_results(cmd2, &res_type)) == CS_SUCCEED) {
     205          40 :                 chk(res_type != CS_CMD_FAIL, "1: ct_results() result_type CS_CMD_FAIL.\n");
     206          40 :                 chk(res_type != CS_COMPUTE_RESULT, "ct_results() unexpected CS_COMPUTE_RESULT.\n");
     207             : 
     208          40 :                 switch ((int) res_type) {
     209             :                 case CS_CMD_SUCCEED:
     210             :                         break;
     211             :                 case CS_CMD_DONE:
     212             :                         break;
     213          10 :                 case CS_ROW_RESULT:
     214          10 :                         datafmt.datatype = CS_CHAR_TYPE;
     215          10 :                         datafmt.format = CS_FMT_NULLTERM;
     216          10 :                         datafmt.maxlength = 256;
     217          10 :                         datafmt.count = 1;
     218          10 :                         datafmt.locale = NULL;
     219          10 :                         check_call(ct_bind, (cmd2, 1, &datafmt, name, &datalength, &ind));
     220             : 
     221          30 :                         while (((ret = ct_fetch(cmd2, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
     222          10 :                                || (ret == CS_ROW_FAIL)) {
     223          10 :                                 row_count += count;
     224          10 :                                 chk(ret != CS_ROW_FAIL, "ct_fetch() CS_ROW_FAIL on row %d.\n", row_count);
     225          10 :                                 if (ret == CS_SUCCEED) {
     226          10 :                                         chk(!strcmp(name, "Bill"), "fetched value '%s' expected 'Bill'\n", name);
     227             :                                 } else {
     228             :                                         break;
     229             :                                 }
     230             :                         }
     231          10 :                         chk(ret == CS_END_DATA, "ct_fetch() unexpected return %d.\n", (int) ret);
     232          10 :                         break;
     233           0 :                 default:
     234           0 :                         fprintf(stderr, "ct_results() unexpected result_type.\n");
     235           0 :                         return 1;
     236             :                 }
     237             :         }
     238          10 :         chk(results_ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) results_ret);
     239             : 
     240          10 :         intvar = 32;
     241             : 
     242          10 :         check_call(ct_send, (cmd2));
     243             : 
     244          10 :         while ((results_ret = ct_results(cmd2, &res_type)) == CS_SUCCEED) {
     245          40 :                 chk(res_type != CS_CMD_FAIL, "2: ct_results() result_type CS_CMD_FAIL.\n");
     246          40 :                 chk(res_type != CS_COMPUTE_RESULT, "ct_results() unexpected CS_COMPUTE_RESULT.\n");
     247             : 
     248          40 :                 switch ((int) res_type) {
     249             :                 case CS_CMD_SUCCEED:
     250             :                         break;
     251             :                 case CS_CMD_DONE:
     252             :                         break;
     253          10 :                 case CS_ROW_RESULT:
     254          10 :                         datafmt.datatype = CS_CHAR_TYPE;
     255          10 :                         datafmt.format = CS_FMT_NULLTERM;
     256          10 :                         datafmt.maxlength = 256;
     257          10 :                         datafmt.count = 1;
     258          10 :                         datafmt.locale = NULL;
     259          10 :                         check_call(ct_bind, (cmd2, 1, &datafmt, name, &datalength, &ind));
     260             : 
     261          30 :                         while (((ret = ct_fetch(cmd2, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
     262          10 :                                || (ret == CS_ROW_FAIL)) {
     263          10 :                                 row_count += count;
     264          10 :                                 chk(ret != CS_ROW_FAIL, "ct_fetch() CS_ROW_FAIL on row %d.\n", row_count);
     265             : 
     266          10 :                                 if (ret == CS_SUCCEED) {
     267          10 :                                         chk(!strcmp(name, "Freddy"), "fetched value '%s' expected 'Freddy'\n", name);
     268             :                                 } else {
     269             :                                         break;
     270             :                                 }
     271             :                         }
     272          10 :                         chk(ret == CS_END_DATA, "ct_fetch() unexpected return %d.\n", (int) ret);
     273          10 :                         break;
     274           0 :                 default:
     275           0 :                         fprintf(stderr, "ct_results() unexpected result_type.\n");
     276           0 :                         return 1;
     277             :                 }
     278             :         }
     279          10 :         chk(results_ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) results_ret);
     280             : 
     281          10 :         check_call(ct_dynamic, (cmd, CS_DEALLOC, "age", CS_NULLTERM, NULL, CS_UNUSED));
     282             : 
     283          10 :         check_call(ct_send, (cmd));
     284             : 
     285          24 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
     286           4 :                 switch ((int) res_type) {
     287             : 
     288             :                 case CS_CMD_SUCCEED:
     289             :                 case CS_CMD_DONE:
     290             :                         break;
     291             : 
     292             :                 case CS_CMD_FAIL:
     293             :                         break;
     294             : 
     295           0 :                 default:
     296           0 :                         chk(0, "invalid ct_results result type: %d\n", res_type);
     297             :                 }
     298             :         }
     299          10 :         chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
     300             : 
     301             :         /*
     302             :          * check we can prepare again dynamic with same name after deallocation
     303             :          */
     304          10 :         strcpy(cmdbuf, "select name from #ct_dynamic where age = ?");
     305          10 :         check_call(ct_dynamic, (cmd, CS_PREPARE, "age", CS_NULLTERM, cmdbuf, CS_NULLTERM));
     306             : 
     307          10 :         check_call(ct_send, (cmd));
     308             : 
     309          40 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
     310          20 :                 switch ((int) res_type) {
     311             : 
     312             :                 case CS_CMD_SUCCEED:
     313             :                 case CS_CMD_DONE:
     314             :                         break;
     315             : 
     316             :                 case CS_CMD_FAIL:
     317             :                         break;
     318             : 
     319           0 :                 default:
     320           0 :                         chk(0, "invalid ct_results result type: %d\n", res_type);
     321             :                 }
     322             :         }
     323          10 :         chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
     324             : 
     325          10 :         ct_dynamic(cmd, CS_DEALLOC, "invalid", CS_NULLTERM, NULL, CS_UNUSED);
     326          10 :         ct_send(cmd);
     327          20 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED)
     328           0 :                 chk(res_type != CS_ROW_RESULT, "Rows not expected\n");
     329          10 :         chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
     330             : 
     331          10 :         check_call(ct_dynamic, (cmd2, CS_EXECUTE, "age", CS_NULLTERM, NULL, CS_UNUSED));
     332             : 
     333          10 :         intvar = 32;
     334          10 :         intvarsize = 4;
     335          10 :         intvarind = 0;
     336             : 
     337          10 :         datafmt.name[0] = 0;
     338          10 :         datafmt.namelen = 0;
     339          10 :         datafmt.datatype = CS_INT_TYPE;
     340          10 :         datafmt.status = CS_INPUTVALUE;
     341             : 
     342          10 :         check_call(ct_setparam, (cmd2, &datafmt, (CS_VOID *) & intvar, &intvarsize, &intvarind));
     343          10 :         check_call(ct_send, (cmd2));
     344             : 
     345             :         /* all tests succeeded */
     346             : 
     347          10 :         cleanup();
     348          10 :         return 0;
     349             : }

Generated by: LCOV version 1.13