LCOV - code coverage report
Current view: top level - src/odbc/unittests - putdata.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 113 116 97.4 %
Date: 2024-03-23 09:12:27 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : 
       3             : /* Test for SQLPutData */
       4             : 
       5             : static const char test_text[] =
       6             :         "Nel mezzo del cammin di nostra vita\n" "mi ritrovai per una selva oscura\n" "che' la diritta via era smarrita.";
       7             : 
       8             : #define BYTE_AT(n) (((n) * 245 + 123) & 0xff)
       9             : 
      10             : static int
      11             : to_sqlwchar(SQLWCHAR *dst, const char *src, int n)
      12             : {
      13             :         int i;
      14        3060 :         for (i = 0; i < n; ++i)
      15        2904 :                 dst[i] = src[i];
      16         140 :         return n * sizeof(SQLWCHAR);
      17             : }
      18             : 
      19             : static char sql[1024];
      20             : 
      21             : static void
      22          16 : Test(int direct)
      23             : {
      24             :         SQLLEN ind;
      25          16 :         int len = strlen(test_text), n, i;
      26             :         const char *p;
      27             :         char *pp;
      28             :         SQLPOINTER ptr;
      29             :         unsigned char buf[256], *pb;
      30             :         SQLRETURN RetCode;
      31             :         int type, lc, sql_type;
      32             : 
      33             :         /* create table to hold data */
      34          16 :         odbc_command_with_result(odbc_stmt, "DROP TABLE #putdata");
      35          16 :         odbc_command("CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");
      36             : 
      37          16 :         sql_type = SQL_LONGVARCHAR;
      38          16 :         type = SQL_C_CHAR;
      39          16 :         lc = 1;
      40             :         for (;;) {
      41          56 :                 CHKBindParameter(1, SQL_PARAM_INPUT, type, sql_type, 0, 0, (SQLPOINTER) 123, 0, &ind, "S");
      42             :                 /* length required */
      43          56 :                 ind = SQL_LEN_DATA_AT_EXEC(len * lc);
      44             : 
      45             :                 /* 
      46             :                  * test for char 
      47             :                  */
      48             : 
      49          56 :                 if (!direct) {
      50          28 :                         CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");
      51             : 
      52          28 :                         CHKExecute("Ne");
      53             :                 } else {
      54          28 :                         CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
      55             :                 }
      56             : 
      57          56 :                 p = test_text;
      58          56 :                 n = 5;
      59          56 :                 ptr = ((char*)0) + 0xdeadbeef;
      60          56 :                 CHKParamData(&ptr, "Ne");
      61          56 :                 if (ptr != (SQLPOINTER) 123) {
      62           0 :                         fprintf(stderr, "%p\n", ptr);
      63           0 :                         ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
      64             :                 }
      65         336 :                 while (*p) {
      66         280 :                         int l = strlen(p);
      67             : 
      68         280 :                         if (l < n)
      69          56 :                                 n = l;
      70         280 :                         if (type == SQL_C_CHAR) {
      71         140 :                                 CHKPutData((char *) p, n, "S");
      72             :                         } else {
      73             :                                 SQLWCHAR buf[256];
      74         280 :                                 CHKPutData((char *) buf, to_sqlwchar(buf, p, n), "S");
      75             :                         }
      76         280 :                         p += n;
      77         280 :                         n *= 2;
      78             :                 }
      79          56 :                 CHKParamData(&ptr, "S");
      80             : 
      81          56 :                 CHKParamData(&ptr, "E");
      82             : 
      83             :                 /* check state  and reset some possible buffers */
      84          56 :                 odbc_command("DECLARE @i INT");
      85             : 
      86             :                 /* use server ntext if available */
      87          56 :                 if (sql_type == SQL_LONGVARCHAR && odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
      88          24 :                         sql_type = SQL_WLONGVARCHAR;
      89          24 :                         continue;
      90             :                 }
      91             : 
      92          32 :                 if (type != SQL_C_CHAR)
      93             :                         break;
      94             :                 sql_type = SQL_LONGVARCHAR;
      95             :                 type = SQL_C_WCHAR;
      96             :                 lc = sizeof(SQLWCHAR);
      97             :         }
      98             : 
      99             :         /* update row setting binary field */
     100        4080 :         for (i = 0; i < 255; ++i)
     101        4080 :                 buf[i] = BYTE_AT(i);
     102             : 
     103             :         /* 
     104             :          * test for binary 
     105             :          */
     106             : 
     107          16 :         CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 4567, 0, &ind, "S");
     108          16 :         ind = SQL_LEN_DATA_AT_EXEC(254);
     109             : 
     110          16 :         CHKPrepare(T("UPDATE #putdata SET b = ?"), SQL_NTS, "S");
     111             : 
     112          16 :         CHKExecute("Ne");
     113             : 
     114          16 :         pb = buf;
     115          16 :         n = 7;
     116          16 :         CHKParamData(&ptr, "Ne");
     117          16 :         if (ptr != (SQLPOINTER) 4567)
     118           0 :                 ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
     119         112 :         while (pb != (buf + 254)) {
     120          96 :                 int l = buf + 254 - pb;
     121             : 
     122          96 :                 if (l < n)
     123          16 :                         n = l;
     124          96 :                 CHKPutData((char *) pb, n, "S");
     125          96 :                 pb += n;
     126          96 :                 n *= 2;
     127             :         }
     128          16 :         CHKParamData(&ptr, "S");
     129             : 
     130          16 :         CHKParamData(&ptr, "E");
     131             : 
     132             :         /* check state  and reset some possible buffers */
     133          16 :         odbc_command("DECLARE @i2 INT");
     134             : 
     135             : 
     136          16 :         CHKFreeStmt(SQL_RESET_PARAMS, "S");
     137             : 
     138             :         /* check inserts ... there should be all equal rows */
     139          16 :         strcpy(sql, "IF EXISTS(SELECT * FROM #putdata WHERE CONVERT(VARBINARY(255),b) <> 0x");
     140             :         /* append binary */
     141        4080 :         for (i = 0; i < 254; ++i)
     142        4064 :                 sprintf(strchr(sql, 0), "%02x", buf[i]);
     143          16 :         strcat(sql, " OR CONVERT(VARCHAR(255),c) <> '");
     144             :         /* append string */
     145          16 :         pp = strchr(sql, 0);
     146          16 :         p = test_text;
     147             :         do {
     148        1648 :                 *pp++ = *p;
     149        1648 :                 if (*p == '\'')
     150          16 :                         *pp++ = *p;
     151        1648 :         } while(*p++);
     152          16 :         strcat(sql, "') SELECT 1");
     153          16 :         odbc_check_no_row(sql);
     154             : 
     155          16 :         odbc_command("DELETE FROM #putdata");
     156             : 
     157             :         /* test len == 0 case from ML */
     158          16 :         type = SQL_C_CHAR;
     159             :         for (;;) {
     160          48 :                 if (!direct)
     161          16 :                         CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");
     162             : 
     163          32 :                 CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind, "S");
     164             : 
     165          32 :                 ind = SQL_LEN_DATA_AT_EXEC(0);
     166             : 
     167          32 :                 if (!direct)
     168          16 :                         CHKExecute("Ne");
     169             :                 else
     170          16 :                         CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
     171             :                 RetCode = SQL_NEED_DATA;
     172          96 :                 while (RetCode == SQL_NEED_DATA) {
     173          64 :                         RetCode = SQLParamData(odbc_stmt, &ptr);
     174          64 :                         if (RetCode == SQL_NEED_DATA) {
     175          32 :                                 if (type == SQL_C_CHAR) {
     176          16 :                                         CHKPutData("abc", 3, "S");
     177             :                                 } else {
     178             :                                         SQLWCHAR buf[10];
     179          32 :                                         CHKPutData(buf, to_sqlwchar(buf, "abc", 3), "S");
     180             :                                 }
     181             :                         }
     182             :                 }
     183          32 :                 if (type != SQL_C_CHAR)
     184             :                         break;
     185          16 :                 type = SQL_C_WCHAR;
     186          16 :                 odbc_reset_statement();
     187             :         }
     188             : 
     189             :         /* check inserts ... */
     190          16 :         odbc_check_no_row("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE 'abc') SELECT 1");
     191             : 
     192          16 :         odbc_command("DELETE FROM #putdata");
     193             : 
     194             :         /* test putting 0 bytes from Sebastien Flaesch */
     195          16 :         if (odbc_db_is_microsoft()) {
     196             :                 type = SQL_C_CHAR;
     197             :                 for (;;) {
     198          36 :                         if (!direct)
     199          12 :                                 CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");
     200             : 
     201          24 :                         CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 10, 0, (PTR) 2, 10, &ind, "S");
     202             : 
     203          24 :                         ind = SQL_DATA_AT_EXEC;
     204             : 
     205          24 :                         if (!direct)
     206          12 :                                 CHKExecute("Ne");
     207             :                         else
     208          12 :                                 CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
     209             :                         RetCode = SQL_NEED_DATA;
     210          72 :                         while (RetCode == SQL_NEED_DATA) {
     211          48 :                                 RetCode = SQLParamData(odbc_stmt, &ptr);
     212          48 :                                 if (RetCode == SQL_NEED_DATA)
     213          24 :                                         CHKPutData("", 0, "S");
     214             :                         }
     215          24 :                         if (type != SQL_C_CHAR)
     216             :                                 break;
     217          12 :                         type = SQL_C_WCHAR;
     218          12 :                         odbc_reset_statement();
     219             :                 }
     220             : 
     221             :                 /* check inserts ... */
     222          12 :                 odbc_check_no_row("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE '') SELECT 1");
     223             :         }
     224             : 
     225             :         /* TODO test cancel inside SQLExecute */
     226          16 : }
     227             : 
     228             : int
     229           8 : main(int argc, char *argv[])
     230             : {
     231           8 :         odbc_connect();
     232             : 
     233           8 :         Test(0);
     234           8 :         Test(1);
     235             : 
     236           8 :         odbc_disconnect();
     237             : 
     238           8 :         printf("Done.\n");
     239             :         return 0;
     240             : }

Generated by: LCOV version 1.13