LCOV - code coverage report
Current view: top level - src/odbc/unittests - data.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 86 101 85.1 %
Date: 2024-04-18 21:21:48 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /*
       2             :  * Test reading data with SQLBindCol
       3             :  */
       4             : #include "common.h"
       5             : #include <assert.h>
       6             : #include <ctype.h>
       7             : #include "parser.h"
       8             : 
       9             : /*
      10             :  * This test is useful to test odbc_tds2sql function
      11             :  * odbc_tds2sql have some particular cases:
      12             :  * (1) numeric -> binary  numeric is different in ODBC
      13             :  * (2) *       -> binary  dependent from libTDS representation and ODBC one
      14             :  * (3) binary  -> char    TODO
      15             :  * (4) date    -> char    different format
      16             :  * Also we have to check normal char and wide char
      17             :  */
      18             : 
      19             : static int result = 0;
      20             : 
      21             : static int ignore_select_error = 0;
      22             : static int ignore_result = 0;
      23             : 
      24             : static void
      25         560 : Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, const char *expected)
      26             : {
      27             :         char sbuf[1024];
      28             :         unsigned char out_buf[256];
      29         560 :         SQLLEN out_len = 0;
      30             : 
      31         560 :         SQLFreeStmt(odbc_stmt, SQL_UNBIND);
      32         560 :         SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS);
      33             : 
      34             :         /* execute a select to get data as wire */
      35         560 :         sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
      36         560 :         if (strncmp(value_to_convert, "0x", 2) == 0) {
      37          22 :                 if (odbc_db_is_microsoft())
      38          18 :                         sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert);
      39             :                 else
      40           4 :                         sprintf(sbuf, "SELECT CONVERT(%s, %s)", type, value_to_convert);
      41         538 :         } else if (strcmp(type, "SQL_VARIANT") == 0)
      42          64 :                 sprintf(sbuf, "SELECT CONVERT(SQL_VARIANT, %s) AS data", value_to_convert);
      43         474 :         else if (strncmp(value_to_convert, "u&'", 3) == 0)
      44           8 :                 sprintf(sbuf, "SELECT CONVERT(%s, %s) AS data", type, value_to_convert);
      45         560 :         if (ignore_select_error) {
      46         560 :                 if (odbc_command2(sbuf, "SENo") == SQL_ERROR) {
      47          18 :                         odbc_reset_statement();
      48          18 :                         ignore_select_error = 0;
      49          18 :                         ignore_result = 0;
      50          18 :                         return;
      51             :                 }
      52             :         } else {
      53           0 :                 odbc_command(sbuf);
      54             :         }
      55         542 :         SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
      56         542 :         CHKFetch("S");
      57         542 :         CHKFetch("No");
      58         542 :         CHKMoreResults("No");
      59             : 
      60             :         /* test results */
      61         542 :         odbc_c2string(sbuf, out_c_type, out_buf, out_len);
      62             : 
      63         542 :         if (!ignore_result && strcmp(sbuf, expected) != 0) {
      64           0 :                 fprintf(stderr, "Wrong result\n  Got:      %s\n  Expected: %s\n", sbuf, expected);
      65           0 :                 result = 1;
      66             :         }
      67         542 :         ignore_select_error = 0;
      68         542 :         ignore_result = 0;
      69             : }
      70             : 
      71             : static int
      72           0 : get_int(const char *s)
      73             : {
      74             :         char *end;
      75             :         long l;
      76             : 
      77           0 :         if (!s)
      78           0 :                 odbc_fatal(": NULL int\n");
      79           0 :         l = strtol(s, &end, 0);
      80           0 :         if (end[0])
      81           0 :                 odbc_fatal(": Invalid int\n");
      82           0 :         return (int) l;
      83             : }
      84             : 
      85             : static int
      86        1088 : lookup(const char *name, const struct odbc_lookup_int *table)
      87             : {
      88             :         int res;
      89             : 
      90        1088 :         if (!table)
      91           0 :                 return get_int(name);
      92             : 
      93        1088 :         res = odbc_lookup(name, table, SQL_UNKNOWN_TYPE);
      94             : 
      95        1088 :         return res == SQL_UNKNOWN_TYPE ? get_int(name) : res;
      96             : }
      97             : 
      98             : int
      99           8 : main(int argc, char *argv[])
     100             : {
     101           8 :         int cond = 1;
     102             : 
     103             : #define TEST_FILE "data.in"
     104           8 :         const char *in_file = FREETDS_SRCDIR "/" TEST_FILE;
     105             :         FILE *f;
     106             : 
     107           8 :         odbc_connect();
     108             : 
     109           8 :         odbc_init_bools();
     110             : 
     111           8 :         f = fopen(in_file, "r");
     112           8 :         if (!f)
     113           0 :                 f = fopen(TEST_FILE, "r");
     114           8 :         if (!f) {
     115           0 :                 fprintf(stderr, "error opening test file\n");
     116           0 :                 exit(1);
     117             :         }
     118             : 
     119           8 :         odbc_init_parser(f);
     120        1168 :         for (;;) {
     121             :                 char *p;
     122        1176 :                 const char *cmd = odbc_get_cmd_line(&p, &cond);
     123             : 
     124        1176 :                 if (!cmd)
     125             :                         break;
     126             : 
     127             :                 /* select type */
     128        1168 :                 if (!strcmp(cmd, "select")) {
     129        1056 :                         const char *type = odbc_get_str(&p);
     130        1056 :                         const char *value = odbc_get_str(&p);
     131        1056 :                         int c_type = lookup(odbc_get_tok(&p), odbc_sql_c_types);
     132        1056 :                         const char *expected = odbc_get_str(&p);
     133             : 
     134        2224 :                         if (!cond) continue;
     135             : 
     136         536 :                         ignore_select_error = 1;
     137         536 :                         Test(type, value, c_type, expected);
     138         536 :                         continue;
     139             :                 }
     140             :                 /* select type setting condition */
     141         112 :                 if (!strcmp(cmd, "select_cond")) {
     142          32 :                         const char *bool_name = odbc_get_tok(&p);
     143          32 :                         const char *type = odbc_get_tok(&p);
     144          32 :                         const char *value = odbc_get_str(&p);
     145          32 :                         int c_type = lookup(odbc_get_tok(&p), odbc_sql_c_types);
     146          32 :                         const char *expected = odbc_get_str(&p);
     147          32 :                         int save_result = result;
     148             : 
     149          32 :                         if (!bool_name) odbc_fatal(": no condition name\n");
     150          32 :                         if (!cond) continue;
     151             : 
     152          24 :                         ignore_select_error = 1;
     153          24 :                         ignore_result = 1;
     154          24 :                         result = 0;
     155          24 :                         Test(type, value, c_type, expected);
     156          24 :                         odbc_set_bool(bool_name, result == 0);
     157          24 :                         result = save_result;
     158          24 :                         continue;
     159             :                 }
     160             :                 /* execute a sql command */
     161          80 :                 if (!strcmp(cmd, "sql")) {
     162          24 :                         const char *sql = odbc_get_str(&p);
     163             : 
     164          24 :                         if (!cond) continue;
     165             : 
     166          12 :                         odbc_command(sql);
     167          12 :                         continue;
     168             :                 }
     169          56 :                 if (!strcmp(cmd, "sql_cond")) {
     170          56 :                         const char *bool_name = odbc_get_tok(&p);
     171          56 :                         const char *sql = odbc_get_str(&p);
     172             : 
     173          56 :                         if (!cond) continue;
     174             : 
     175          42 :                         odbc_set_bool(bool_name, odbc_command2(sql, "SENo") != SQL_ERROR);
     176          42 :                         continue;
     177             :                 }
     178           0 :                 odbc_fatal(": unknown command\n");
     179             :         }
     180           8 :         odbc_clear_bools();
     181           8 :         fclose(f);
     182             : 
     183           8 :         printf("\n");
     184             : 
     185           8 :         odbc_disconnect();
     186             : 
     187           8 :         if (!result)
     188           8 :                 printf("Done successfully!\n");
     189           8 :         return result;
     190             : }

Generated by: LCOV version 1.13