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

Generated by: LCOV version 1.13