LCOV - code coverage report
Current view: top level - clients/odbc/tests - ODBCtester.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 156 202 77.2 %
Date: 2025-03-26 20:06:40 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024, 2025 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #ifdef _MSC_VER
      14             : #include <WTypes.h>
      15             : #endif
      16             : #include <stdio.h>
      17             : #include <stdlib.h>
      18             : #include <stdint.h>
      19             : #include <string.h>
      20             : #include <ctype.h>
      21             : #include <inttypes.h>
      22             : #include <wchar.h>
      23             : 
      24             : /**** Define the ODBC Version our ODBC driver complies with ****/
      25             : #define ODBCVER 0x0352          /* Important: this must be defined before include of sql.h and sqlext.h */
      26             : #include <sql.h>
      27             : #include <sqlext.h>
      28             : 
      29             : static void
      30           0 : prerr(SQLSMALLINT tpe, SQLHANDLE hnd, const char *func, const char *pref)
      31             : {
      32           0 :         SQLCHAR state[6];
      33           0 :         SQLINTEGER errnr;
      34           0 :         SQLCHAR msg[256];
      35           0 :         SQLSMALLINT msglen;
      36           0 :         SQLRETURN ret;
      37             : 
      38           0 :         ret = SQLGetDiagRec(tpe, hnd, 1, state, &errnr, msg, sizeof(msg), &msglen);
      39           0 :         switch (ret) {
      40           0 :         case SQL_SUCCESS_WITH_INFO:
      41           0 :                 if (msglen >= (signed int) sizeof(msg))
      42           0 :                         fprintf(stderr, "(message truncated)\n");
      43             :                 /* fall through */
      44             :         case SQL_SUCCESS:
      45           0 :                 fprintf(stderr, "%s: %s: SQLstate %s, Errnr %d, Message %s\n", func, pref, (char*)state, (int)errnr, (char*)msg);
      46           0 :                 break;
      47           0 :         case SQL_INVALID_HANDLE:
      48           0 :                 fprintf(stderr, "%s: %s, invalid handle passed to error function\n", func, pref);
      49           0 :                 break;
      50           0 :         case SQL_ERROR:
      51           0 :                 fprintf(stderr, "%s: %s, unexpected error from SQLGetDiagRec\n", func, pref);
      52           0 :                 break;
      53             :         case SQL_NO_DATA:
      54             :                 break;
      55           0 :         default:
      56           0 :                 fprintf(stderr, "%s: %s, weird return value from SQLGetDiagRec\n", func, pref);
      57           0 :                 break;
      58             :         }
      59           0 : }
      60             : 
      61             : static void
      62          33 : check(SQLRETURN ret, SQLSMALLINT tpe, SQLHANDLE hnd, const char *func)
      63             : {
      64          33 :         switch (ret) {
      65             :         case SQL_SUCCESS:
      66             :                 break;
      67           0 :         case SQL_SUCCESS_WITH_INFO:
      68           0 :                 prerr(tpe, hnd, func, "Info");
      69           0 :                 break;
      70           0 :         case SQL_ERROR:
      71           0 :                 prerr(tpe, hnd, func, "Error");
      72           0 :                 break;
      73             :         case SQL_NO_DATA:
      74             :                 break;
      75           0 :         case SQL_INVALID_HANDLE:
      76           0 :                 fprintf(stderr, "%s: Error: invalid handle\n", func);
      77           0 :                 break;
      78           0 :         default:
      79           0 :                 fprintf(stderr, "%s: Unexpected return value\n", func);
      80           0 :                 break;
      81             :         }
      82          33 : }
      83             : 
      84             : static size_t
      85           3 : retrieveDiagMsg(SQLHANDLE stmt, char * outp, size_t outp_len)
      86             : {
      87           3 :         SQLCHAR state[6];
      88           3 :         SQLINTEGER errnr = 0;
      89           3 :         char msg[256];
      90           3 :         SQLSMALLINT msglen = 0;
      91           3 :         SQLRETURN ret = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, state, &errnr, (SQLCHAR *) msg, sizeof(msg), &msglen);
      92           3 :         if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
      93             :                 /* The message layout is: "[MonetDB][ODBC Driver 11.46.0][MonetDB-Test]error/warning text".
      94             :                    The ODBC driver version numbers changes in time. Overwrite it to get a stable output */
      95           3 :                 if (strncmp(msg, "[MonetDB][ODBC Driver 11.", 25) == 0) {
      96           3 :                         return snprintf(outp, outp_len, "SQLstate %s, Errnr %d, Message [MonetDB][ODBC Driver 11.##.#]%s\n", (char*)state, (int)errnr, strchr(msg + 25, ']') + 1);
      97             :                 }
      98           0 :                 return snprintf(outp, outp_len, "SQLstate %s, Errnr %d, Message %s\n", (char*)state, (int)errnr, (char*)msg);
      99             :         }
     100             :         return 0;
     101             : }
     102             : 
     103             : static void
     104           3 : compareResult(char * testname, char * testresult, char * expected)
     105             : {
     106           3 :         if (strcmp(expected, testresult) != 0) {
     107           0 :                 fprintf(stderr, "Testing %s\nGotten:\n%s\nExpected:\n%s\n", testname, testresult, expected);
     108             :         }
     109           3 : }
     110             : 
     111             : #define LLFMT                   "%" PRId64
     112             : 
     113             : static SQLRETURN
     114           2 : testGetDataTruncatedString(SQLHANDLE stmt, SWORD ctype)
     115             : {
     116           2 :         SQLRETURN ret;
     117           2 :         SQLLEN RowCount = 0;
     118           2 :         SWORD NumResultCols = 0;
     119             : 
     120           2 :         size_t outp_len = 800;
     121           2 :         char * outp = malloc(outp_len);
     122           2 :         size_t pos = 0;
     123             : 
     124             : //      char * sql = "select tag as \"qtag\", sessionid as \"sessionid\", username as \"username\", started as \"started\", status as \"status\", query as \"query\", finished as \"finished\", maxworkers as \"maxworkers\", footprint as \"footprint\" from sys.queue() where query like '/*e6dbd251960c49bbbeff9784fa70c86d*/%';";
     125           2 :         char * sql = "select cast('12345678901234567890 abcdefghijklmnopqrstuvwxyz' as clob) as val;";
     126           2 :         ret = SQLExecDirect(stmt, (SQLCHAR *) sql, SQL_NTS);
     127           2 :         pos += snprintf(outp + pos, outp_len - pos, "SQLExecDirect\n");
     128           2 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect");
     129             : 
     130           2 :         ret = SQLRowCount(stmt, &RowCount);
     131           2 :         pos += snprintf(outp + pos, outp_len - pos, "SQLRowCount is " LLFMT "\n", (int64_t) RowCount);
     132           2 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLRowCount");
     133             : 
     134           2 :         ret = SQLNumResultCols(stmt, &NumResultCols);
     135           2 :         pos += snprintf(outp + pos, outp_len - pos, "SQLNumResultCols is %d\n", NumResultCols);
     136           2 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLNumResultCols");
     137             : 
     138           2 :         ret = SQLFetch(stmt);
     139           2 :         pos += snprintf(outp + pos, outp_len - pos, "SQLFetch\n");
     140           2 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLFetch");
     141             : 
     142           4 :         for (SWORD col = 1; col <= NumResultCols; col++) {
     143           2 :                 char buf[99];
     144           2 :                 wchar_t wbuf[99];
     145           2 :                 char buf2[99];
     146           2 :                 wchar_t wbuf2[99];
     147           2 :                 SQLLEN vallen = 0;
     148           2 :                 SQLLEN NumAttr = 0;
     149           2 :                 char * ctype_str = (ctype == SQL_C_CHAR ? "SQL_C_CHAR" : ctype == SQL_C_WCHAR ? "SQL_C_WCHAR" : "NYI");
     150             : 
     151             :                 /* retrieve query result column metadata */
     152           2 :                 ret = SQLColAttribute(stmt, (UWORD)col, SQL_DESC_CONCISE_TYPE, (PTR)&buf, (SQLLEN)20, NULL, &NumAttr);
     153           2 :                 pos += snprintf(outp + pos, outp_len - pos, "SQLColAttribute(%d, SQL_DESC_CONCISE_TYPE) returns %d, NumAttr " LLFMT "\n", col, ret, (int64_t) NumAttr);
     154           2 :                 ret = SQLColAttribute(stmt, (UWORD)col, SQL_DESC_LENGTH, (PTR)&buf, (SQLLEN)20, NULL, &NumAttr);
     155           2 :                 pos += snprintf(outp + pos, outp_len - pos, "SQLColAttribute(%d, SQL_DESC_LENGTH) returns %d, NumAttr " LLFMT "\n", col, ret, (int64_t) NumAttr);
     156           2 :                 ret = SQLColAttribute(stmt, (UWORD)col, SQL_DESC_DISPLAY_SIZE, (PTR)&buf, (SQLLEN)20, NULL, &NumAttr);
     157           2 :                 pos += snprintf(outp + pos, outp_len - pos, "SQLColAttribute(%d, SQL_DESC_DISPLAY_SIZE) returns %d, NumAttr " LLFMT "\n", col, ret, (int64_t) NumAttr);
     158             : 
     159             :                 /* test SQLGetData(SQL_C_(W)CHAR, 20) with a restricted buffer size (20) for the queried string value (47) */
     160           3 :                 ret = SQLGetData(stmt, (UWORD)col, (SWORD)ctype, ctype == SQL_C_WCHAR ? (PTR)&wbuf : (PTR)&buf, (SQLLEN)20, &vallen);
     161           2 :                 if (ctype == SQL_C_WCHAR) {
     162             :                         /* snprintf does not allow printing wchar strings. convert it to a char string */
     163             :                         /* tried: wcstombs(buf, wbuf, 99); but it doesn't work */
     164             :                         /* workaround: just empty the buffer to get a stable output on all platforms (power8 gives a different output) */
     165           1 :                         buf[0] = 0;
     166             :                 }
     167           2 :                 pos += snprintf(outp + pos, outp_len - pos, "SQLGetData(%d, %s, 20) returns %d, vallen " LLFMT ", buf: '%s'\n", col, ctype_str, ret, (int64_t) vallen, buf);
     168             :                 /* we expect SQL_SUCCESS_WITH_INFO with warning msg set, fetch them */
     169           2 :                 if (ret == SQL_SUCCESS_WITH_INFO) {
     170           2 :                         pos += retrieveDiagMsg(stmt, outp + pos, outp_len - pos);
     171             : 
     172             :                         /* get the next data part of the value (this is how SQLGetData is intended to be used to get large data in chunks) */
     173           3 :                         ret = SQLGetData(stmt, (UWORD)col, (SWORD)ctype, ctype == SQL_C_WCHAR ? (PTR)&wbuf2 : (PTR)&buf2, (SQLLEN)30, &vallen);
     174           2 :                         if (ctype == SQL_C_WCHAR) {
     175             :                                 /* tried: wcstombs(buf2, wbuf2, 99); but it doesn't work */
     176             :                                 /* workaround: just empty the buffer to get a stable output on all platforms (power8 gives a different output) */
     177           1 :                                 buf2[0] = 0;
     178             :                         }
     179           2 :                         pos += snprintf(outp + pos, outp_len - pos, "SQLGetData(%d, %s, 30) returns %d, vallen " LLFMT ", buf: '%s'\n", col, ctype_str, ret, (int64_t) vallen, buf2);
     180           2 :                         if (ret == SQL_SUCCESS_WITH_INFO) {
     181           1 :                                 pos += retrieveDiagMsg(stmt, outp + pos, outp_len - pos);
     182           1 :                                 ret = SQL_SUCCESS;
     183             :                         }
     184             :                 }
     185           2 :                 check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData(col)");
     186             :         }
     187             : 
     188           2 :         if (ctype == SQL_C_CHAR) {
     189           1 :                 compareResult("testGetDataTruncatedString(SQL_C_CHAR)", outp,
     190             :                         "SQLExecDirect\nSQLRowCount is 1\nSQLNumResultCols is 1\nSQLFetch\n"
     191             :                         "SQLColAttribute(1, SQL_DESC_CONCISE_TYPE) returns 0, NumAttr -9\n"   /* -9 = SQL_WVARCHAR */
     192             :                         "SQLColAttribute(1, SQL_DESC_LENGTH) returns 0, NumAttr 47\n"
     193             :                         "SQLColAttribute(1, SQL_DESC_DISPLAY_SIZE) returns 0, NumAttr 47\n"
     194             :                         "SQLGetData(1, SQL_C_CHAR, 20) returns 1, vallen 47, buf: '1234567890123456789'\n"
     195             :                         "SQLstate 01004, Errnr 0, Message [MonetDB][ODBC Driver 11.##.#][MonetDB-Test]String data, right truncated\n"
     196             :                         "SQLGetData(1, SQL_C_CHAR, 30) returns 0, vallen 28, buf: '0 abcdefghijklmnopqrstuvwxyz'\n");
     197             :         } else
     198           1 :         if (ctype == SQL_C_WCHAR) {
     199           1 :                 compareResult("testGetDataTruncatedString(SQL_C_WCHAR)", outp,
     200             :                         "SQLExecDirect\nSQLRowCount is 1\nSQLNumResultCols is 1\nSQLFetch\n"
     201             :                         "SQLColAttribute(1, SQL_DESC_CONCISE_TYPE) returns 0, NumAttr -9\n"   /* -9 = SQL_WVARCHAR */
     202             :                         "SQLColAttribute(1, SQL_DESC_LENGTH) returns 0, NumAttr 47\n"
     203             :                         "SQLColAttribute(1, SQL_DESC_DISPLAY_SIZE) returns 0, NumAttr 47\n"
     204             :                         "SQLGetData(1, SQL_C_WCHAR, 20) returns 1, vallen 94, buf: ''\n"
     205             :                         "SQLstate 01004, Errnr 0, Message [MonetDB][ODBC Driver 11.##.#][MonetDB-Test]String data, right truncated\n"
     206             :                         "SQLGetData(1, SQL_C_WCHAR, 30) returns 1, vallen 76, buf: ''\n"
     207             :                         "SQLstate 01004, Errnr 0, Message [MonetDB][ODBC Driver 11.##.#][MonetDB-Test]String data, right truncated\n");
     208             :         }
     209             : 
     210             :         /* cleanup */
     211           2 :         free(outp);
     212           2 :         return ret;
     213             : }
     214             : 
     215             : static SQLRETURN
     216           1 : testGetDataGUID(SQLHANDLE stmt)
     217             : {
     218           1 :         SQLRETURN ret;
     219           1 :         SQLLEN RowCount = 0;
     220           1 :         SWORD NumResultCols = 0;
     221             : 
     222           1 :         size_t outp_len = 1800;
     223           1 :         char * outp = malloc(outp_len);
     224           1 :         size_t pos = 0;
     225             : 
     226           1 :         char * sql = "select cast(NULL as uuid) as valnil, cast('eda7b074-3e0f-4bef-bdec-19c61bedb18f' as uuid) as val1, cast('beefc4f7-0264-4735-9b7a-75fd371ef803' as uuid) as val2;";
     227           1 :         ret = SQLExecDirect(stmt, (SQLCHAR *) sql, SQL_NTS);
     228           1 :         pos += snprintf(outp + pos, outp_len - pos, "SQLExecDirect\n");
     229           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect");
     230             : 
     231           1 :         ret = SQLRowCount(stmt, &RowCount);
     232           1 :         pos += snprintf(outp + pos, outp_len - pos, "SQLRowCount is " LLFMT "\n", (int64_t) RowCount);
     233           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLRowCount");
     234             : 
     235           1 :         ret = SQLNumResultCols(stmt, &NumResultCols);
     236           1 :         pos += snprintf(outp + pos, outp_len - pos, "SQLNumResultCols is %d\n", NumResultCols);
     237           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLNumResultCols");
     238             : 
     239           1 :         ret = SQLFetch(stmt);
     240           1 :         pos += snprintf(outp + pos, outp_len - pos, "SQLFetch\n");
     241           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLFetch");
     242             : 
     243           4 :         for (SWORD col = 1; col <= NumResultCols; col++) {
     244           3 :                 char buf[99];
     245           3 :                 SQLGUID guid_val;
     246           3 :                 char guid_str_val[40];
     247           3 :                 SQLLEN vallen = 0;
     248           3 :                 SQLLEN NumAttr = 0;
     249             : 
     250             :                 /* retrieve query result column metadata */
     251           3 :                 ret = SQLColAttribute(stmt, (UWORD)col, SQL_DESC_CONCISE_TYPE, (PTR)&buf, (SQLLEN)20, NULL, &NumAttr);
     252           3 :                 pos += snprintf(outp + pos, outp_len - pos, "SQLColAttribute(%d, SQL_DESC_CONCISE_TYPE) returns %d, NumAttr " LLFMT "\n", col, ret, (int64_t) NumAttr);
     253           3 :                 ret = SQLColAttribute(stmt, (UWORD)col, SQL_DESC_DISPLAY_SIZE, (PTR)&buf, (SQLLEN)20, NULL, &NumAttr);
     254           3 :                 pos += snprintf(outp + pos, outp_len - pos, "SQLColAttribute(%d, SQL_DESC_DISPLAY_SIZE) returns %d, NumAttr " LLFMT "\n", col, ret, (int64_t) NumAttr);
     255             : 
     256             :                 /* test SQLGetData(SQL_C_CHAR) */
     257           3 :                 ret = SQLGetData(stmt, (UWORD)col, (SWORD)SQL_C_CHAR, (PTR)&guid_str_val, (SQLLEN)40, &vallen);
     258           6 :                 pos += snprintf(outp + pos, outp_len - pos, "SQLGetData(%d, SQL_C_CHAR, 36) returns %d, vallen " LLFMT ", str_val: '%s'\n",
     259           3 :                         col, ret, (int64_t) vallen, (vallen == SQL_NULL_DATA) ? "NULL" : guid_str_val);
     260           3 :                 check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData(col)");
     261             : 
     262             :                 /* test SQLGetData(SQL_C_GUID) */
     263           3 :                 ret = SQLGetData(stmt, (UWORD)col, (SWORD)SQL_C_GUID, (PTR)&guid_val, (SQLLEN)16, &vallen);
     264           3 :                 pos += snprintf(outp + pos, outp_len - pos, "SQLGetData(%d, SQL_C_GUID, 16) returns %d, vallen " LLFMT ", data_val: ", col, ret, (int64_t) vallen);
     265           3 :                 if (vallen == SQL_NULL_DATA)
     266           1 :                         pos += snprintf(outp + pos, outp_len - pos, "NULL\n");
     267             :                 else
     268           2 :                         pos += snprintf(outp + pos, outp_len - pos, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
     269           2 :                                 guid_val.Data1, guid_val.Data2, guid_val.Data3,
     270           2 :                                 guid_val.Data4[0], guid_val.Data4[1], guid_val.Data4[2], guid_val.Data4[3], guid_val.Data4[4], guid_val.Data4[5], guid_val.Data4[6], guid_val.Data4[7]);
     271           3 :                 check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData(col)");
     272             :         }
     273             : 
     274           1 :         compareResult("testGetDataGUID()", outp,
     275             :                         "SQLExecDirect\nSQLRowCount is 1\nSQLNumResultCols is 3\nSQLFetch\n"
     276             :                         "SQLColAttribute(1, SQL_DESC_CONCISE_TYPE) returns 0, NumAttr -11\n"  /* -11 = SQL_GUID */
     277             :                         "SQLColAttribute(1, SQL_DESC_DISPLAY_SIZE) returns 0, NumAttr 36\n"
     278             :                         "SQLGetData(1, SQL_C_CHAR, 36) returns 0, vallen -1, str_val: 'NULL'\n"
     279             :                         "SQLGetData(1, SQL_C_GUID, 16) returns 0, vallen -1, data_val: NULL\n"
     280             :                         "SQLColAttribute(2, SQL_DESC_CONCISE_TYPE) returns 0, NumAttr -11\n"  /* -11 = SQL_GUID */
     281             :                         "SQLColAttribute(2, SQL_DESC_DISPLAY_SIZE) returns 0, NumAttr 36\n"
     282             :                         "SQLGetData(2, SQL_C_CHAR, 36) returns 0, vallen 36, str_val: 'eda7b074-3e0f-4bef-bdec-19c61bedb18f'\n"
     283             :                         "SQLGetData(2, SQL_C_GUID, 16) returns 0, vallen 16, data_val: eda7b074-3e0f-4bef-bdec-19c61bedb18f\n"
     284             :                         "SQLColAttribute(3, SQL_DESC_CONCISE_TYPE) returns 0, NumAttr -11\n"  /* -11 = SQL_GUID */
     285             :                         "SQLColAttribute(3, SQL_DESC_DISPLAY_SIZE) returns 0, NumAttr 36\n"
     286             :                         "SQLGetData(3, SQL_C_CHAR, 36) returns 0, vallen 36, str_val: 'beefc4f7-0264-4735-9b7a-75fd371ef803'\n"
     287             :                         "SQLGetData(3, SQL_C_GUID, 16) returns 0, vallen 16, data_val: beefc4f7-0264-4735-9b7a-75fd371ef803\n");
     288             : 
     289             :         /* cleanup */
     290           1 :         free(outp);
     291           1 :         return ret;
     292             : }
     293             : 
     294             : int
     295           1 : main(int argc, char **argv)
     296             : {
     297           1 :         SQLRETURN ret;
     298           1 :         SQLHANDLE env;
     299           1 :         SQLHANDLE dbc;
     300           1 :         SQLHANDLE stmt;
     301           1 :         char *dsn = "MonetDB";
     302           1 :         char *user = "monetdb";
     303           1 :         char *pass = "monetdb";
     304             : 
     305           1 :         if (argc > 1)
     306           1 :                 dsn = argv[1];
     307           1 :         if (argc > 2)
     308           0 :                 user = argv[2];
     309           0 :         if (argc > 3)
     310           0 :                 pass = argv[3];
     311           1 :         if (argc > 4 || *dsn == '-') {
     312           0 :                 fprintf(stderr, "Wrong arguments. Usage: %s [datasource [user [password]]]\n", argv[0]);
     313           0 :                 exit(1);
     314             :         }
     315             : 
     316           1 :         ret = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &env);
     317           1 :         if (!SQL_SUCCEEDED(ret)) {
     318           0 :                 fprintf(stderr, "Cannot allocate ODBC environment handle!\n");
     319           0 :                 exit(1);
     320             :         }
     321             : 
     322           1 :         ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (uintptr_t) SQL_OV_ODBC3, 0);
     323           1 :         check(ret, SQL_HANDLE_ENV, env, "SQLSetEnvAttr (SQL_ATTR_ODBC_VERSION ODBC3)");
     324             : 
     325           1 :         ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
     326           1 :         check(ret, SQL_HANDLE_ENV, env, "SQLAllocHandle (DBC)");
     327             : 
     328           1 :         ret = SQLConnect(dbc, (SQLCHAR *) dsn, SQL_NTS, (SQLCHAR *) user, SQL_NTS, (SQLCHAR *) pass, SQL_NTS);
     329           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLConnect");
     330           1 :         if (!SQL_SUCCEEDED(ret)) {
     331           0 :                 fprintf(stderr, "Cannot connect!\n");
     332           0 :                 exit(1);
     333             :         }
     334             : 
     335           1 :         ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
     336           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLAllocHandle (STMT)");
     337             : 
     338             :         /* run tests */
     339           1 :         ret = testGetDataTruncatedString(stmt, SQL_C_CHAR);
     340           1 :         check(ret, SQL_HANDLE_STMT, stmt, "testGetDataTruncatedString(STMT, SQL_C_CHAR)");
     341             : 
     342           1 :         ret = SQLCloseCursor(stmt);
     343           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLCloseCursor");
     344             : 
     345           1 :         ret = testGetDataTruncatedString(stmt, SQL_C_WCHAR);
     346           1 :         check(ret, SQL_HANDLE_STMT, stmt, "testGetDataTruncatedString(STMT, SQL_C_WCHAR)");
     347             : 
     348           1 :         ret = SQLCloseCursor(stmt);
     349           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLCloseCursor");
     350             : 
     351           1 :         ret = testGetDataGUID(stmt);
     352           1 :         check(ret, SQL_HANDLE_STMT, stmt, "testGetDataGUID(STMT)");
     353             : 
     354             :         /* cleanup */
     355           1 :         ret = SQLFreeHandle(SQL_HANDLE_STMT, stmt);
     356           1 :         check(ret, SQL_HANDLE_STMT, stmt, "SQLFreeHandle (STMT)");
     357             : 
     358           1 :         ret = SQLDisconnect(dbc);
     359           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLDisconnect");
     360             : 
     361           1 :         ret = SQLFreeHandle(SQL_HANDLE_DBC, dbc);
     362           1 :         check(ret, SQL_HANDLE_DBC, dbc, "SQLFreeHandle (DBC)");
     363             : 
     364           1 :         ret = SQLFreeHandle(SQL_HANDLE_ENV, env);
     365           1 :         check(ret, SQL_HANDLE_ENV, env, "SQLFreeHandle (ENV)");
     366             : 
     367           1 :         return 0;
     368             : }

Generated by: LCOV version 1.14