LCOV - code coverage report
Current view: top level - src/dblib/unittests - t0002.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 95 116 81.9 %
Date: 2025-07-02 09:40:27 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* 
       2             :  * Purpose: Test buffering
       3             :  * Functions: dbclrbuf dbgetrow dbsetopt 
       4             :  */
       5             : #if 0
       6             :         # Find functions with:
       7             :         sed -ne'/db/ s/.*\(db[[:alnum:]_]*\)(.*/\1/gp' src/dblib/unittests/t0002.c |sort -u |fmt
       8             : #endif
       9             : 
      10             : #include "common.h"
      11             : #include <assert.h>
      12             : 
      13             : #include <freetds/bool.h>
      14             : 
      15             : static bool failed = false;
      16             : 
      17             : static void
      18        1010 : verify(int i, int testint, char *teststr)
      19             : {
      20             :         char expected[1024];
      21             : 
      22        1010 :         sprintf(expected, "row %03d", i);
      23             : 
      24        1010 :         if (testint != i) {
      25           0 :                 failed = true;
      26           0 :                 fprintf(stderr, "Failed.  Expected i to be %d, was %d\n", i, testint);
      27           0 :                 abort();
      28             :         }
      29        1010 :         if (0 != strncmp(teststr, expected, strlen(expected))) {
      30           0 :                 failed = true;
      31           0 :                 fprintf(stderr, "Failed.  Expected s to be |%s|, was |%s|\n", expected, teststr);
      32           0 :                 abort();
      33             :         }
      34        1010 :         printf("Read a row of data -> %d %s\n", testint, teststr);
      35        1010 : }
      36             : 
      37          10 : TEST_MAIN()
      38             : {
      39             :         LOGINREC *login;
      40             :         DBPROCESS *dbproc;
      41             :         DBINT testint;
      42             :         STATUS rc;
      43             :         int i, iresults;
      44             :         char teststr[1024];
      45             :         int rows_in_buffer, limit_rows;
      46             : 
      47          10 :         const int buffer_count = 10;
      48          10 :         const int rows_to_add = 50;
      49             : 
      50          10 :         set_malloc_options();
      51             : 
      52          10 :         read_login_info(argc, argv);
      53             : 
      54          10 :         printf("Starting %s\n", argv[0]);
      55             : 
      56             :         /* Fortify_EnterScope(); */
      57          10 :         dbinit();
      58             : 
      59          10 :         dberrhandle(syb_err_handler);
      60          10 :         dbmsghandle(syb_msg_handler);
      61             : 
      62          10 :         printf("About to logon\n");
      63             : 
      64          10 :         login = dblogin();
      65          10 :         DBSETLPWD(login, PASSWORD);
      66          10 :         DBSETLUSER(login, USER);
      67          10 :         DBSETLAPP(login, "t0002");
      68             : 
      69          10 :         printf("About to open %s..%s\n", SERVER, DATABASE);
      70             : 
      71          10 :         dbproc = dbopen(login, SERVER);
      72          10 :         if (strlen(DATABASE))
      73          10 :                 dbuse(dbproc, DATABASE);
      74          10 :         dbloginfree(login);
      75             : 
      76          10 :         printf("Setting row buffer to 10 rows\n");
      77             : #ifdef MICROSOFT_DBLIB
      78             :         dbsetopt(dbproc, DBBUFFER, "10");
      79             : #else
      80          10 :         dbsetopt(dbproc, DBBUFFER, "10", 0);
      81             : #endif
      82             : 
      83          10 :         sql_cmd(dbproc); /* drop table if exists */
      84          10 :         dbsqlexec(dbproc);
      85          10 :         while (dbresults(dbproc) != NO_MORE_RESULTS) {
      86             :                 /* nop */
      87             :         }
      88          10 :         if (dbresults(dbproc) != NO_MORE_RESULTS) {
      89           0 :                 printf("Failed: dbresults call after NO_MORE_RESULTS should return NO_MORE_RESULTS.\n");
      90           0 :                 failed = true;
      91             :         }
      92             : 
      93          10 :         sql_cmd(dbproc); /* create table */
      94          10 :         dbsqlexec(dbproc);
      95          10 :         while (dbresults(dbproc) != NO_MORE_RESULTS) {
      96             :                 /* nop */
      97             :         }
      98             : 
      99         500 :         for (i = 1; i <= rows_to_add; i++) {
     100         500 :                 sql_cmd(dbproc);
     101         500 :                 dbsqlexec(dbproc);
     102         500 :                 while (dbresults(dbproc) != NO_MORE_RESULTS) {
     103             :                         /* nop */
     104             :                 }
     105             :         }
     106             : 
     107          10 :         sql_cmd(dbproc);        /* two result sets */
     108          10 :         dbsqlexec(dbproc);
     109             : 
     110          30 :         for (iresults=1; iresults <= 2; iresults++ ) {
     111          20 :                 printf("fetching resultset %i\n", iresults);
     112          20 :                 if (dbresults(dbproc) != SUCCEED) {
     113           0 :                         fprintf(stderr, "Was expecting a result set %d.\n", iresults);
     114           0 :                         if( iresults == 2 )
     115           0 :                                 fprintf(stderr, "Buffering with multiple resultsets is broken.\n");
     116           0 :                         exit(1);
     117             :                 }
     118             :                 rows_in_buffer = 0;
     119             : 
     120          40 :                 for (i = 1; i <= dbnumcols(dbproc); i++)
     121          40 :                         printf("col %d is [%s]\n", i, dbcolname(dbproc, i));
     122             : 
     123          20 :                 dbbind(dbproc, 1, INTBIND, 0, (BYTE *) & testint);
     124          20 :                 dbbind(dbproc, 2, STRINGBIND, 0, (BYTE *) teststr);
     125             : 
     126             :                 /* Fetch a result set */
     127             :                 /* Second resultset stops at row 46 */
     128          20 :                 limit_rows = rows_to_add - (iresults == 2 ? 4 : 0);
     129         150 :                 for (i=0; i < limit_rows;) {
     130             : 
     131         110 :                         printf("clearing %d rows from buffer\n", rows_in_buffer ? buffer_count - 1 : buffer_count);
     132             : #ifdef MICROSOFT_DBLIB
     133             :                         if (i == 0) {
     134             :                                 rc = dbnextrow(dbproc);
     135             :                                 assert(rc == REG_ROW);
     136             :                                 ++i;
     137             :                                 rows_in_buffer = 1;
     138             :                         }
     139             : #endif
     140         110 :                         dbclrbuf(dbproc, buffer_count);
     141         110 :                         rows_in_buffer = rows_in_buffer ? 1 : 0;
     142             : 
     143             :                         do {
     144             :                                 int rc;
     145             : 
     146         960 :                                 i++;
     147         960 :                                 if (REG_ROW != (rc = dbnextrow(dbproc))) {
     148           0 :                                         failed = true;
     149           0 :                                         fprintf(stderr, "Failed: Expected a row (%s:%d)\n", __FILE__, __LINE__);
     150           0 :                                         if (rc == BUF_FULL)
     151           0 :                                                 fprintf(stderr, "Failed: dbnextrow returned BUF_FULL (%d).  Fix dbclrbuf.\n", rc);
     152           0 :                                         exit(1);
     153             :                                 }
     154         960 :                                 ++rows_in_buffer;
     155         960 :                                 verify(i, testint, teststr);
     156         960 :                         } while (rows_in_buffer < buffer_count && i < limit_rows);
     157             : 
     158         110 :                         if (rows_in_buffer == buffer_count) {
     159             :                                 /* The buffer should be full */
     160         100 :                                 assert(BUF_FULL == dbnextrow(dbproc));
     161             :                         }
     162             :                 }
     163          20 :                 if (iresults == 1) {
     164          10 :                         printf("clearing %d rows from buffer\n", buffer_count);
     165          10 :                         dbclrbuf(dbproc, buffer_count);
     166          10 :                         while (dbnextrow(dbproc) != NO_MORE_ROWS) {
     167           0 :                                 abort(); /* All rows were read: should not enter loop */
     168             :                         }
     169             :                 }
     170             :         }
     171          10 :         printf("\n");
     172             : 
     173             :         /* 
     174             :          * Now test the buffered rows.  
     175             :          * Should be operating on rows 37-46 of 2nd resultset 
     176             :          */
     177          10 :         rc = dbgetrow(dbproc, 1);
     178          10 :         if(rc != NO_MORE_ROWS)  /* row 1 is not among the 31-40 in the buffer */
     179           0 :                 fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc);
     180          10 :         assert(rc == NO_MORE_ROWS);
     181             : 
     182          10 :         rc = dbgetrow(dbproc, 37);
     183          10 :         if(rc != REG_ROW)
     184           0 :                 fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc);
     185          10 :         assert(rc == REG_ROW);
     186          10 :         verify(37, testint, teststr);   /* first buffered row should be 37 */
     187             : 
     188          10 :         rc = dbnextrow(dbproc);
     189          10 :         if(rc != REG_ROW)
     190           0 :                 fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc);
     191          10 :         assert(rc == REG_ROW);
     192          10 :         verify(38, testint, teststr);   /* next buffered row should be 38 */
     193             : 
     194          10 :         rc = dbgetrow(dbproc, 11);
     195          10 :         assert(rc == NO_MORE_ROWS);     /* only 10 (not 11) rows buffered */
     196             : 
     197          10 :         rc = dbgetrow(dbproc, 46);
     198          10 :         assert(rc == REG_ROW);
     199          10 :         verify(46, testint, teststr);   /* last buffered row should be 46 */
     200             : 
     201             :         /* Attempt dbnextrow when buffer has no space (10 out of 10 in use). */
     202          10 :         rc = dbnextrow(dbproc);
     203          10 :         assert(rc == BUF_FULL);
     204             : 
     205          10 :         dbclrbuf(dbproc, 3);            /* remove rows 37, 38, and 39 */
     206             : 
     207          10 :         rc = dbnextrow(dbproc);
     208          10 :         assert(rc == REG_ROW);
     209          10 :         verify(47, testint, teststr);   /* fetch row from database, should be 47 */
     210             : 
     211          10 :         rc = dbnextrow(dbproc);
     212          10 :         assert(rc == REG_ROW);
     213          10 :         verify(48, testint, teststr);   /* fetch row from database, should be 48 */
     214             : 
     215             :         /* buffer contains 8 rows (40-47) try removing 10 rows */
     216          10 :         dbclrbuf(dbproc, buffer_count);
     217             : 
     218          10 :         while (dbnextrow(dbproc) != NO_MORE_ROWS) {
     219             :                 /* waste rows 49-50 */
     220             :         }
     221             : 
     222          10 :         dbclose(dbproc); /* close while buffer not cleared: OK */
     223             : 
     224          10 :         dbexit();
     225             : 
     226          10 :         printf("%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
     227          10 :         return failed ? 1 : 0;
     228             : }

Generated by: LCOV version 1.13