LCOV - code coverage report
Current view: top level - src/odbc/unittests - type.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 36 43 83.7 %
Date: 2024-03-23 09:12:27 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : #include <assert.h>
       3             : 
       4             : struct type
       5             : {
       6             :         SQLSMALLINT type;
       7             :         const char *name;
       8             :         unsigned flags;
       9             : };
      10             : 
      11             : #define FLAG_C  1
      12             : #define FLAG_SQL  2
      13             : 
      14             : #define TYPE_C(s) {s, #s, FLAG_C }
      15             : #define TYPE_SQL(s) {s, #s, FLAG_SQL }
      16             : #define TYPE_BOTH(s,s2) {s, #s, FLAG_SQL|FLAG_C }
      17             : /* 
      18             :  * Same define with test for constants
      19             :  *  #define TYPE_BOTH(s,s2) {s, #s, (FLAG_SQL|FLAG_C)+((1/!(s-s2))-1) }
      20             :  */
      21             : static const struct type types[] = {
      22             :         TYPE_BOTH(SQL_C_CHAR, SQL_CHAR),
      23             :         TYPE_BOTH(SQL_C_LONG, SQL_INTEGER),
      24             :         TYPE_BOTH(SQL_C_SHORT, SQL_SMALLINT),
      25             :         TYPE_BOTH(SQL_C_FLOAT, SQL_REAL),
      26             :         TYPE_BOTH(SQL_C_DOUBLE, SQL_DOUBLE),
      27             :         TYPE_BOTH(SQL_C_NUMERIC, SQL_NUMERIC),
      28             :         TYPE_C(SQL_C_DEFAULT),
      29             :         TYPE_C(SQL_C_DATE),
      30             :         TYPE_C(SQL_C_TIME),
      31             : /* MS ODBC do not support SQL_TIMESTAMP for IPD type while we support it */
      32             : /*      TYPE_C(SQL_C_TIMESTAMP), */
      33             :         TYPE_BOTH(SQL_C_TIMESTAMP, SQL_TIMESTAMP),
      34             :         TYPE_BOTH(SQL_C_TYPE_DATE, SQL_TYPE_DATE),
      35             :         TYPE_BOTH(SQL_C_TYPE_TIME, SQL_TYPE_TIME),
      36             :         TYPE_BOTH(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP),
      37             :         TYPE_C(SQL_C_INTERVAL_YEAR),
      38             :         TYPE_C(SQL_C_INTERVAL_MONTH),
      39             :         TYPE_C(SQL_C_INTERVAL_DAY),
      40             :         TYPE_C(SQL_C_INTERVAL_HOUR),
      41             :         TYPE_C(SQL_C_INTERVAL_MINUTE),
      42             :         TYPE_C(SQL_C_INTERVAL_SECOND),
      43             :         TYPE_C(SQL_C_INTERVAL_YEAR_TO_MONTH),
      44             :         TYPE_C(SQL_C_INTERVAL_DAY_TO_HOUR),
      45             :         TYPE_C(SQL_C_INTERVAL_DAY_TO_MINUTE),
      46             :         TYPE_C(SQL_C_INTERVAL_DAY_TO_SECOND),
      47             :         TYPE_C(SQL_C_INTERVAL_HOUR_TO_MINUTE),
      48             :         TYPE_C(SQL_C_INTERVAL_HOUR_TO_SECOND),
      49             :         TYPE_C(SQL_C_INTERVAL_MINUTE_TO_SECOND),
      50             :         TYPE_BOTH(SQL_C_BINARY, SQL_BINARY),
      51             :         TYPE_BOTH(SQL_C_BIT, SQL_BIT),
      52             :         TYPE_C(SQL_C_SBIGINT),
      53             :         TYPE_C(SQL_C_UBIGINT),
      54             :         TYPE_BOTH(SQL_C_TINYINT, SQL_TINYINT),
      55             :         TYPE_C(SQL_C_SLONG),
      56             :         TYPE_C(SQL_C_SSHORT),
      57             :         TYPE_C(SQL_C_STINYINT),
      58             :         TYPE_C(SQL_C_ULONG),
      59             :         TYPE_C(SQL_C_USHORT),
      60             :         TYPE_C(SQL_C_UTINYINT),
      61             :         TYPE_BOTH(SQL_C_GUID, SQL_GUID),
      62             : 
      63             :         TYPE_SQL(SQL_BIGINT),
      64             :         TYPE_SQL(SQL_VARBINARY),
      65             :         TYPE_SQL(SQL_LONGVARBINARY),
      66             :         TYPE_SQL(SQL_VARCHAR),
      67             :         TYPE_SQL(SQL_LONGVARCHAR),
      68             :         TYPE_SQL(SQL_DECIMAL),
      69             :         TYPE_SQL(SQL_FLOAT),
      70             :         {0, NULL}
      71             : };
      72             : 
      73             : static const char *
      74             : get_type_name(SQLSMALLINT type)
      75             : {
      76         472 :         const struct type *p = types;
      77             : 
      78       17448 :         for (; p->name; ++p)
      79       18392 :                 if (p->type == type)
      80             :                         return p->name;
      81             :         return "(unknown)";
      82             : }
      83             : 
      84             : static int result = 0;
      85             : 
      86             : static void
      87             : check_msg(int check, const char *msg)
      88             : {
      89         720 :         if (check)
      90             :                 return;
      91           0 :         fprintf(stderr, "Check failed: %s\n", msg);
      92           0 :         result = 1;
      93             : }
      94             : 
      95             : int
      96           8 : main(int argc, char **argv)
      97             : {
      98             :         const struct type *p;
      99             :         char buf[16];
     100             :         SQLINTEGER ind;
     101             :         SQLLEN lind;
     102             :         SQLHDESC desc;
     103             : 
     104           8 :         odbc_connect();
     105             : 
     106             :         /*
     107             :          * test setting two time a descriptor
     108             :          * success all user allocated are ARD or APD so type cheching can be done
     109             :          * TODO freeing descriptor dissociate it from statements
     110             :          */
     111             : 
     112             :         /* test C types */
     113         368 :         for (p = types; p->name; ++p) {
     114         360 :                 if (SQL_SUCCEEDED
     115             :                     (SQLBindParameter(odbc_stmt, 1, SQL_PARAM_INPUT, p->type, SQL_VARCHAR, (SQLUINTEGER) (-1), 0, buf, 16, &lind))) {
     116             :                         SQLSMALLINT concise_type, type, code;
     117             :                         SQLHDESC desc;
     118             : 
     119         304 :                         concise_type = type = code = 0;
     120             : 
     121             :                         /* get APD */
     122         304 :                         SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof(desc), &ind);
     123             : 
     124         304 :                         CHKGetDescField(desc, 1, SQL_DESC_TYPE, &type, sizeof(SQLSMALLINT), &ind, "S");
     125         304 :                         CHKGetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, &concise_type, sizeof(SQLSMALLINT), &ind, "S");
     126         304 :                         CHKGetDescField(desc, 1, SQL_DESC_DATETIME_INTERVAL_CODE, &code, sizeof(SQLSMALLINT), &ind, "S");
     127         912 :                         printf("Setted type %s -> [%d (%s), %d (%s), %d]\n",
     128             :                                p->name, (int) concise_type, get_type_name(concise_type), (int) type, get_type_name(type), code);
     129         608 :                         check_msg(p->flags & FLAG_C, "Type not C successed to be set in APD");
     130             :                 } else {
     131             :                         SQLSMALLINT concise_type, type, code;
     132             :                         SQLHDESC desc;
     133             : 
     134          56 :                         concise_type = type = code = 0;
     135             : 
     136          56 :                         fprintf(stderr, "Error setting type %d (%s)\n", (int) p->type, p->name);
     137             : 
     138          56 :                         concise_type = p->type;
     139          56 :                         SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof(desc), &ind);
     140          56 :                         if (SQL_SUCCEEDED
     141             :                             (SQLSetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, TDS_INT2PTR(concise_type), sizeof(SQLSMALLINT))))
     142             :                         {
     143           0 :                                 CHKGetDescField(desc, 1, SQL_DESC_TYPE, &type, sizeof(SQLSMALLINT), &ind, "S");
     144           0 :                                 CHKGetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, &concise_type, sizeof(SQLSMALLINT), &ind, "S");
     145           0 :                                 CHKGetDescField(desc, 1, SQL_DESC_DATETIME_INTERVAL_CODE, &code, sizeof(SQLSMALLINT), &ind, "S");
     146           0 :                                 printf("Setted type %s -> [%d (%s), %d (%s), %d]\n",
     147             :                                        p->name,
     148             :                                        (int) concise_type, get_type_name(concise_type), (int) type, get_type_name(type), code);
     149           0 :                                 check_msg(p->flags & FLAG_C, "Type not C successed to be set in APD");
     150             :                         } else {
     151          56 :                                 check_msg(!(p->flags & FLAG_C), "Type C failed to be set in APD");
     152             :                         }
     153             :                 }
     154             :         }
     155             : 
     156           8 :         printf("\n\n");
     157             : 
     158             :         /* test SQL types */
     159           8 :         SQLGetStmtAttr(odbc_stmt, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind);
     160         368 :         for (p = types; p->name; ++p) {
     161         360 :                 SQLSMALLINT concise_type = p->type;
     162             : 
     163         360 :                 if (SQL_SUCCEEDED
     164             :                     (SQLSetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, TDS_INT2PTR(concise_type), sizeof(SQLSMALLINT)))) {
     165             :                         SQLSMALLINT concise_type, type, code;
     166             : 
     167         168 :                         concise_type = type = code = 0;
     168             : 
     169         168 :                         CHKGetDescField(desc, 1, SQL_DESC_TYPE, &type, sizeof(SQLSMALLINT), &ind, "S");
     170         168 :                         CHKGetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, &concise_type, sizeof(SQLSMALLINT), &ind, "S");
     171         168 :                         CHKGetDescField(desc, 1, SQL_DESC_DATETIME_INTERVAL_CODE, &code, sizeof(SQLSMALLINT), &ind, "S");
     172         504 :                         printf("Setted type %s -> [%d (%s), %d (%s), %d]\n",
     173             :                                p->name, (int) concise_type, get_type_name(concise_type), (int) type, get_type_name(type), code);
     174         336 :                         check_msg(p->flags & FLAG_SQL, "Type not SQL successed to be set in IPD");
     175             :                 } else {
     176         192 :                         fprintf(stderr, "Error setting type %d (%s)\n", (int) p->type, p->name);
     177         192 :                         check_msg(!(p->flags & FLAG_SQL), "Type SQL failed to be set in IPD");
     178             :                 }
     179             :         }
     180             : 
     181           8 :         odbc_disconnect();
     182             : 
     183           8 :         return result;
     184             : }

Generated by: LCOV version 1.13