LCOV - code coverage report
Current view: top level - src/odbc/unittests - binary_test.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 46 55 83.6 %
Date: 2025-01-18 11:50:39 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /**
       2             :  * Summary: Freetds binary patch test.
       3             :  * Author:  Gerhard Esterhuizen <ge AT swistgroup.com>
       4             :  * Date:    April 2003
       5             :  */
       6             : 
       7             : #include "common.h"
       8             : #include <assert.h>
       9             : 
      10             : #define ERR_BUF_SIZE 256
      11             : /* 
      12             :    Name of table used by the test. Should contain single column,
      13             :    of IMAGE type and should contain NO rows at time of program invocation.
      14             : */
      15             : #define TEST_TABLE_NAME "#binary_test"
      16             : 
      17             : /*
      18             :   Size (in bytes) of the test pattern written to and read from
      19             :   the database.
      20             : */
      21             : #define TEST_BUF_LEN (1024*128)
      22             : 
      23             : 
      24             : static unsigned char *buf;
      25             : 
      26             : static void
      27             : show_error(const char *where, const char *what)
      28             : {
      29           0 :         printf("ERROR in %s: %s.\n", where, what);
      30             : }
      31             : 
      32             : static void
      33             : clean_up(void)
      34             : {
      35           8 :         free(buf);
      36           8 :         odbc_disconnect();
      37             : }
      38             : 
      39             : static int
      40           8 : test_insert(void *buf, SQLLEN buflen)
      41             : {
      42           8 :         SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
      43             :         SQLLEN strlen_or_ind;
      44           8 :         const char *qstr = "insert into " TEST_TABLE_NAME " values (?)";
      45             : 
      46           8 :         assert(odbc_conn);
      47           8 :         assert(odbc_env);
      48             : 
      49             :         /* allocate new statement handle */
      50           8 :         CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");
      51             : 
      52             :         /* execute query */
      53           8 :         CHKPrepare(T(qstr), SQL_NTS, "SI");
      54             : 
      55           8 :         strlen_or_ind = buflen;
      56           8 :         CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, (SQLUINTEGER) (-1), 0, buf, buflen,
      57             :                                &strlen_or_ind, "SI");
      58             : 
      59           8 :         CHKExecute("SI");
      60             : 
      61             :         /* this command shouldn't fail */
      62           8 :         odbc_command("DECLARE @i INT");
      63             : 
      64           8 :         SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
      65           8 :         return 0;
      66             : }
      67             : 
      68             : 
      69             : static int
      70           8 : test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
      71             : {
      72           8 :         SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
      73           8 :         SQLLEN strlen_or_ind = 0;
      74           8 :         const char *qstr = "select * from " TEST_TABLE_NAME;
      75             : 
      76           8 :         assert(odbc_conn);
      77           8 :         assert(odbc_env);
      78             : 
      79             :         /* allocate new statement handle */
      80           8 :         CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");
      81             : 
      82             :         /* execute query */
      83           8 :         CHKExecDirect(T(qstr), SQL_NTS, "SINo");
      84             : 
      85             :         /* fetch first page of first result row of unbound column */
      86           8 :         CHKFetch("S");
      87             : 
      88           8 :         strlen_or_ind = 0;
      89           8 :         CHKGetData(1, SQL_C_BINARY, buf, buflen, &strlen_or_ind, "SINo");
      90             : 
      91           8 :         *bytes_returned = ((strlen_or_ind > buflen || (strlen_or_ind == SQL_NO_TOTAL)) ? buflen : strlen_or_ind);
      92             : 
      93             :         /* ensure that this was the only row */
      94           8 :         CHKFetch("No");
      95             : 
      96           8 :         SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
      97           8 :         ODBC_FREE();
      98           8 :         return 0;
      99             : }
     100             : 
     101             : #define BYTE_AT(n) (((n) * 123) & 0xff)
     102             : 
     103             : int
     104           8 : main(void)
     105             : {
     106             :         int i;
     107             :         SQLLEN bytes_returned;
     108             : 
     109             :         /* do not allocate so big memory in stack */
     110           8 :         buf = (unsigned char *) malloc(TEST_BUF_LEN);
     111             : 
     112           8 :         odbc_connect();
     113             : 
     114           8 :         odbc_command("create table " TEST_TABLE_NAME " (im IMAGE)");
     115           8 :         odbc_command("SET TEXTSIZE 1000000");
     116             : 
     117             :         /* populate test buffer with ramp */
     118     1048584 :         for (i = 0; i < TEST_BUF_LEN; i++) {
     119     1048576 :                 buf[i] = BYTE_AT(i);
     120             :         }
     121             : 
     122             :         /* insert test pattern into database */
     123           8 :         if (test_insert(buf, TEST_BUF_LEN) == -1) {
     124             :                 clean_up();
     125           0 :                 return -1;
     126             :         }
     127             : 
     128           8 :         memset(buf, 0, TEST_BUF_LEN);
     129             : 
     130             :         /* read test pattern from database */
     131           8 :         if (test_select(buf, TEST_BUF_LEN, &bytes_returned) == -1) {
     132             :                 clean_up();
     133           0 :                 return -1;
     134             :         }
     135             : 
     136             :         /* compare inserted and read back test patterns */
     137           8 :         if (bytes_returned != TEST_BUF_LEN) {
     138           0 :                 show_error("main(): comparing buffers", "Mismatch in input and output pattern sizes.");
     139           0 :                 printf("Expected %lu got %lu\n", (unsigned long) TEST_BUF_LEN, (unsigned long) bytes_returned);
     140             :                 clean_up();
     141           0 :                 return -1;
     142             :         }
     143             : 
     144     1048576 :         for (i = 0; i < TEST_BUF_LEN; ++i) {
     145     1048576 :                 if (buf[i] != BYTE_AT(i)) {
     146           0 :                         printf("mismatch at pos %d %d != %d\n", i, buf[i], BYTE_AT(i));
     147           0 :                         show_error("main(): comparing buffers", "Mismatch in input and output patterns.");
     148             :                         clean_up();
     149           0 :                         return -1;
     150             :                 }
     151             :         }
     152             : 
     153           8 :         printf("Input and output buffers of length %d match.\nTest passed.\n", TEST_BUF_LEN);
     154             :         clean_up();
     155           8 :         return 0;
     156             : }

Generated by: LCOV version 1.13