LCOV - code coverage report
Current view: top level - src/ctlib/unittests - ct_dynamic.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 165 206 80.1 %
Date: 2025-01-18 12:13:41 Functions: 3 5 60.0 %

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

Generated by: LCOV version 1.13