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

Generated by: LCOV version 1.13