LCOV - code coverage report
Current view: top level - src/ctlib/unittests - lang_ct_param.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 101 119 84.9 %
Date: 2025-07-02 09:40:27 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : 
       3             : #include <stdarg.h>
       4             : 
       5             : static const char *query =
       6             :         "insert into #ctparam_lang (name,name2,age,cost,bdate,fval) values (@in1, @in2, @in3, @moneyval, @dateval, @floatval)";
       7             : 
       8             : static int insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames);
       9             : 
      10             : /* Testing: binding of data via ct_param */
      11          10 : TEST_MAIN()
      12             : {
      13          10 :         int errCode = 0;
      14             :         
      15             :         CS_CONTEXT *ctx;
      16             :         CS_CONNECTION *conn;
      17             :         CS_COMMAND *cmd;
      18          10 :         int verbose = 0;
      19             : 
      20             :         CS_CHAR cmdbuf[4096];
      21             : 
      22          10 :         if (argc > 1 && (0 == strcmp(argv[1], "-v")))
      23           0 :                 verbose = 1;
      24             : 
      25          10 :         printf("%s: submit language query with variables using ct_param\n", __FILE__);
      26          10 :         if (verbose) {
      27           0 :                 printf("Trying login\n");
      28             :         }
      29          10 :         check_call(try_ctlogin, (&ctx, &conn, &cmd, verbose));
      30          10 :         error_to_stdout = true;
      31             : 
      32          10 :         strcpy(cmdbuf, "create table #ctparam_lang (id numeric identity not null, \
      33             :                 name varchar(30), name2 varchar(20), age int, cost money, bdate datetime, fval float) ");
      34             : 
      35          10 :         check_call(run_command, (cmd, cmdbuf));
      36             : 
      37             :         /* test by name */
      38          10 :         errCode = insert_test(conn, cmd, 1);
      39             :         /* if worked, test by position */
      40          10 :         if (0 == errCode)
      41          10 :                 errCode = insert_test(conn, cmd, 0);
      42          10 :         query = "insert into #ctparam_lang (name,name2,age,cost,bdate,fval) values (?, ?, ?, ?, ?, ?)";
      43          10 :         if (0 == errCode)
      44          10 :                 errCode = insert_test(conn, cmd, 0);
      45             : 
      46          10 :         if (verbose && (0 == errCode))
      47           0 :                 printf("lang_ct_param tests successful\n");
      48             : 
      49          10 :         if (verbose) {
      50           0 :                 printf("Trying logout\n");
      51             :         }
      52          10 :         check_call(try_ctlogout, (ctx, conn, cmd, verbose));
      53             : 
      54          10 :         return errCode;
      55             : }
      56             : 
      57             : static int 
      58          30 : insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames)
      59             : {
      60             :         CS_CONTEXT *ctx;
      61             : 
      62             :         CS_RETCODE ret;
      63             :         CS_INT res_type;
      64             : 
      65             :         CS_DATAFMT datafmt;
      66             :         CS_DATAFMT srcfmt;
      67             :         CS_DATAFMT destfmt;
      68             :         CS_INT intvar;
      69             :         CS_FLOAT floatvar;
      70             :         CS_MONEY moneyvar;
      71             :         CS_DATEREC datevar;
      72             :         char moneystring[10];
      73             :         char dummy_name[30];
      74             :         char dummy_name2[20];
      75             :         CS_INT destlen;
      76          30 :         CS_INT rowsAffected = -1;
      77          30 :         int rows_found = 0;
      78             : 
      79             :         /* clear table */
      80          30 :         run_command(cmd, "delete #ctparam_lang");
      81             : 
      82             :         /*
      83             :          * Assign values to the variables used for parameter passing.
      84             :          */
      85             : 
      86          30 :         intvar = 2;
      87          30 :         floatvar = 0.12;
      88          30 :         strcpy(dummy_name, "joe blow");
      89          30 :         strcpy(dummy_name2, "");
      90          30 :         strcpy(moneystring, "300.90");
      91             : 
      92             :         /*
      93             :          * Clear and setup the CS_DATAFMT structures used to convert datatypes.
      94             :          */
      95             : 
      96          30 :         memset(&srcfmt, 0, sizeof(CS_DATAFMT));
      97             :         srcfmt.datatype = CS_CHAR_TYPE;
      98          30 :         srcfmt.maxlength = (CS_INT) strlen(moneystring);
      99          30 :         srcfmt.precision = 5;
     100          30 :         srcfmt.scale = 2;
     101             :         srcfmt.locale = NULL;
     102             : 
     103          30 :         memset(&destfmt, 0, sizeof(CS_DATAFMT));
     104          30 :         destfmt.datatype = CS_MONEY_TYPE;
     105          30 :         destfmt.maxlength = sizeof(CS_MONEY);
     106          30 :         destfmt.precision = 5;
     107          30 :         destfmt.scale = 2;
     108             :         destfmt.locale = NULL;
     109             : 
     110             :         /*
     111             :          * Convert the string representing the money value
     112             :          * to a CS_MONEY variable. Since this routine does not have the
     113             :          * context handle, we use the property functions to get it.
     114             :          */
     115          30 :         check_call(ct_cmd_props, (cmd, CS_GET, CS_PARENT_HANDLE, &conn, CS_UNUSED, NULL));
     116          30 :         check_call(ct_con_props, (conn, CS_GET, CS_PARENT_HANDLE, &ctx, CS_UNUSED, NULL));
     117          30 :         check_call(cs_convert, (ctx, &srcfmt, (CS_VOID *) moneystring, &destfmt, &moneyvar, &destlen));
     118             : 
     119             :         /*
     120             :          * create the command
     121             :          */
     122          30 :         check_call(ct_command, (cmd, CS_LANG_CMD, (CS_CHAR *) query, (CS_INT) strlen(query), CS_UNUSED));
     123             : 
     124             :         /*
     125             :          * Clear and setup the CS_DATAFMT structure, then pass
     126             :          * each of the parameters for the query.
     127             :          */
     128          30 :         memset(&datafmt, 0, sizeof(datafmt));
     129          30 :         if (useNames)
     130          10 :                 strcpy(datafmt.name, "@in1");
     131             :         else
     132             :                 datafmt.name[0] = 0;
     133          30 :         datafmt.maxlength = 255;
     134          30 :         datafmt.namelen = CS_NULLTERM;
     135             :         datafmt.datatype = CS_CHAR_TYPE;
     136          30 :         datafmt.status = CS_INPUTVALUE;
     137             : 
     138             :         /*
     139             :          * The character string variable is filled in by the RPC so pass NULL
     140             :          * for the data 0 for data length, and -1 for the indicator arguments.
     141             :          */
     142          30 :         check_call(ct_param, (cmd, &datafmt, dummy_name, (CS_INT) strlen(dummy_name), 0));
     143             : 
     144          30 :         if (useNames)
     145          10 :                 strcpy(datafmt.name, "@in2");
     146             :         else
     147          20 :                 datafmt.name[0] = 0;
     148          30 :         datafmt.maxlength = 255;
     149          30 :         datafmt.namelen = CS_NULLTERM;
     150          30 :         datafmt.datatype = CS_CHAR_TYPE;
     151          30 :         datafmt.status = CS_INPUTVALUE;
     152             : 
     153          30 :         check_call(ct_param, (cmd, &datafmt, dummy_name2, (CS_INT) strlen(dummy_name2), 0));
     154             : 
     155          30 :         if (useNames)
     156          10 :                 strcpy(datafmt.name, "@in3");
     157             :         else
     158          20 :                 datafmt.name[0] = 0;
     159          30 :         datafmt.namelen = CS_NULLTERM;
     160          30 :         datafmt.datatype = CS_INT_TYPE;
     161          30 :         datafmt.status = CS_INPUTVALUE;
     162             : 
     163          30 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & intvar, CS_SIZEOF(CS_INT), 0));
     164             : 
     165          30 :         if (useNames)
     166          10 :                 strcpy(datafmt.name, "@moneyval");
     167             :         else
     168          20 :                 datafmt.name[0] = 0;
     169          30 :         datafmt.namelen = CS_NULLTERM;
     170          30 :         datafmt.datatype = CS_MONEY_TYPE;
     171          30 :         datafmt.status = CS_INPUTVALUE;
     172             : 
     173          30 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & moneyvar, CS_SIZEOF(CS_MONEY), 0));
     174             : 
     175          30 :         if (useNames)
     176          10 :                 strcpy(datafmt.name, "@dateval");
     177             :         else
     178          20 :                 datafmt.name[0] = 0;
     179          30 :         datafmt.namelen = CS_NULLTERM;
     180          30 :         datafmt.datatype = CS_DATETIME_TYPE;
     181          30 :         datafmt.status = CS_INPUTVALUE;
     182          30 :         memset(&datevar, 0, sizeof(CS_DATEREC));
     183          30 :         datevar.dateyear = 2003;
     184          30 :         datevar.datemonth = 2;
     185          30 :         datevar.datedmonth = 1;
     186             : 
     187          30 :         check_call(ct_param, (cmd, &datafmt, &datevar, 0, 0));
     188             : 
     189          30 :         if (useNames)
     190          10 :                 strcpy(datafmt.name, "@floatval");
     191             :         else
     192          20 :                 datafmt.name[0] = 0;
     193          30 :         datafmt.namelen = CS_NULLTERM;
     194          30 :         datafmt.datatype = CS_FLOAT_TYPE;
     195          30 :         datafmt.status = CS_INPUTVALUE;
     196             : 
     197          30 :         check_call(ct_param, (cmd, &datafmt, &floatvar, 0, 0));
     198             : 
     199             :         /*
     200             :          * Send the command to the server
     201             :          */
     202          30 :         check_call(ct_send, (cmd));
     203             : 
     204             :         /*
     205             :          * Process the results.
     206             :          */
     207         120 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
     208          60 :                 switch ((int) res_type) {
     209             : 
     210          60 :                 case CS_CMD_SUCCEED:
     211             :                 case CS_CMD_DONE:
     212             :                         {
     213          60 :                                 CS_INT rowsAffected=0;
     214          60 :                                 ct_res_info(cmd, CS_ROW_COUNT, &rowsAffected, CS_UNUSED, NULL);
     215          60 :                                 if (1 != rowsAffected) 
     216           0 :                                         fprintf(stderr, "insert touched %d rows instead of 1\n", rowsAffected);
     217             :                                 else
     218             :                                         rows_found = 1;
     219             :                         }
     220          60 :                         break;
     221             : 
     222           0 :                 case CS_CMD_FAIL:
     223             :                         /*
     224             :                          * The server encountered an error while
     225             :                          * processing our command.
     226             :                          */
     227           0 :                         fprintf(stderr, "ct_results returned CS_CMD_FAIL.\n");
     228           0 :                         break;
     229             : 
     230           0 :                 case CS_STATUS_RESULT:
     231             :                         /*
     232             :                          * The server encountered an error while
     233             :                          * processing our command.
     234             :                          */
     235           0 :                         fprintf(stderr, "ct_results returned CS_STATUS_RESULT.\n");
     236           0 :                         break;
     237             : 
     238           0 :                 default:
     239             :                         /*
     240             :                          * We got something unexpected.
     241             :                          */
     242           0 :                         fprintf(stderr, "ct_results returned unexpected result type %d\n", res_type);
     243           0 :                         return 1;
     244             :                 }
     245             :         }
     246          30 :         if (ret != CS_END_RESULTS) {
     247           0 :                 fprintf(stderr, "ct_results returned unexpected result %d.\n", (int) ret);
     248           0 :                 exit(1);
     249             :         }
     250             : 
     251          30 :         if (!rows_found) {
     252           0 :                 fprintf(stderr, "expected 1 rows inserted, inserted %d.\n", (int) rowsAffected);
     253           0 :                 exit(1);
     254             :         }
     255             : 
     256             :         /* test row inserted */
     257          30 :         check_call(run_command, (cmd, "if not exists("
     258             :                    "select * from #ctparam_lang where name = 'joe blow' and name2 is not null and age = 2"
     259             :                    ") select 1"));
     260             : 
     261          30 :         return 0;
     262             : }

Generated by: LCOV version 1.13