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

          Line data    Source code
       1             : /* 
       2             :  * Purpose: Test sending and receiving TEXT datatype
       3             :  * Functions: dbbind dbmoretext dbreadtext dbtxptr dbtxtimestamp dbwritetext 
       4             :  */
       5             : 
       6             : #include "common.h"
       7             : 
       8             : #include <freetds/bool.h>
       9             : 
      10             : #define BLOB_BLOCK_SIZE 4096
      11             : 
      12             : static char *testargs[] = { "", FREETDS_SRCDIR "/data.bin", "t0014.out" };
      13             : 
      14             : static int
      15          16 : test(int argc, char **argv, bool over4k)
      16             : {
      17          16 :         const int rows_to_add = 3;
      18             :         LOGINREC *login;
      19             :         DBPROCESS *dbproc;
      20             :         DBPROCESS *blobproc;
      21             :         int i;
      22             :         DBINT testint;
      23             :         FILE *fp;
      24             :         ptrdiff_t result;
      25             :         long isiz;
      26             :         char *blob, *rblob;
      27             :         unsigned char *textPtr, *timeStamp;
      28             :         char objname[256];
      29             :         char sqlCmd[256];
      30             :         char rbuf[BLOB_BLOCK_SIZE];
      31             :         size_t numread;
      32             :         int numtowrite, numwritten;
      33             : 
      34          16 :         set_malloc_options();
      35             : 
      36          16 :         read_login_info(argc, argv);
      37          16 :         printf("Starting %s\n", argv[0]);
      38          16 :         dbinit();
      39             : 
      40          16 :         dberrhandle(syb_err_handler);
      41          16 :         dbmsghandle(syb_msg_handler);
      42             : 
      43          16 :         printf("About to logon\n");
      44             : 
      45          16 :         login = dblogin();
      46          16 :         DBSETLPWD(login, PASSWORD);
      47          16 :         DBSETLUSER(login, USER);
      48          16 :         DBSETLAPP(login, "t0014");
      49             : 
      50          16 :         printf("About to open %s..%s for user '%s'\n", SERVER, DATABASE, USER);
      51             : 
      52          16 :         dbproc = dbopen(login, SERVER);
      53          16 :         blobproc = dbopen(login, SERVER);
      54          16 :         if (strlen(DATABASE)) {
      55          16 :                 dbuse(dbproc, DATABASE);
      56          16 :                 dbuse(blobproc, DATABASE);
      57             :         }
      58          16 :         dbloginfree(login);
      59          16 :         printf("After logon\n");
      60             : 
      61          16 :         printf("About to read binary input file\n");
      62             : 
      63          16 :         if (argc == 1) {
      64             :                 argv = testargs;
      65             :                 argc = 3;
      66             :         }
      67           0 :         if (argc < 3) {
      68           0 :                 fprintf(stderr, "Usage: %s infile outfile\n", argv[0]);
      69           0 :                 return 1;
      70             :         }
      71             : 
      72          16 :         if ((fp = fopen(argv[1], "rb")) == NULL) {
      73           0 :                 fprintf(stderr, "Cannot open input file: %s\n", argv[1]);
      74           0 :                 return 2;
      75             :         }
      76          16 :         result = fseek(fp, 0, SEEK_END);
      77          16 :         isiz = ftell(fp);
      78          16 :         result = fseek(fp, 0, SEEK_SET);
      79             : 
      80          16 :         blob = (char *) malloc(isiz);
      81          16 :         assert(blob);
      82          16 :         result = fread((void *) blob, isiz, 1, fp);
      83          16 :         assert(result == 1);
      84          16 :         fclose(fp);
      85             : 
      86             :         /* FIXME this test seem to not work using temporary tables (sybase?)... */
      87          16 :         printf("Dropping table\n");
      88          16 :         sql_cmd(dbproc);
      89          16 :         dbsqlexec(dbproc);
      90          16 :         while (dbresults(dbproc) != NO_MORE_RESULTS) {
      91             :                 /* nop */
      92             :         }
      93             : 
      94          16 :         printf("creating table\n");
      95          16 :         sql_cmd(dbproc);
      96          16 :         dbsqlexec(dbproc);
      97          16 :         while (dbresults(dbproc) != NO_MORE_RESULTS) {
      98             :                 /* nop */
      99             :         }
     100             : 
     101             : 
     102          16 :         printf("insert\n");
     103          64 :         for (i = 0; i < rows_to_add; i++) {
     104          48 :                 sql_cmd(dbproc);
     105          48 :                 dbsqlexec(dbproc);
     106          48 :                 while (dbresults(dbproc) != NO_MORE_RESULTS) {
     107             :                         /* nop */
     108             :                 }
     109             :         }
     110             : 
     111          36 :         for (i = 0; i < rows_to_add; i++) {
     112          40 :                 sql_cmd(dbproc);
     113          40 :                 dbsqlexec(dbproc);
     114          40 :                 if (dbresults(dbproc) != SUCCEED) {
     115           0 :                         fprintf(stderr, "Error inserting blob\n");
     116           0 :                         return 4;
     117             :                 }
     118             : 
     119          76 :                 while ((result = dbnextrow(dbproc)) != NO_MORE_ROWS) {
     120          40 :                         result = REG_ROW;
     121          40 :                         result = DBTXPLEN;
     122          40 :                         strcpy(objname, "dblib0014.PigTure");
     123          40 :                         textPtr = dbtxptr(dbproc, 1);
     124          40 :                         timeStamp = dbtxtimestamp(dbproc, 1);
     125             : 
     126             : #ifdef DBTDS_7_2
     127          40 :                         if (!textPtr && !timeStamp && dbtds(dbproc) >= DBTDS_7_2) {
     128           4 :                                 printf("Protocol 7.2+ detected, test not supported\n");
     129           4 :                                 free(blob);
     130           4 :                                 dbexit();
     131           4 :                                 exit(0);
     132             :                         }
     133             : #endif
     134             : 
     135             :                         /* leave NULL on first row */
     136          36 :                         if (i == 0)
     137          12 :                                 continue;
     138             : 
     139             :                         /*
     140             :                          * Use #ifdef if you want to test dbmoretext mode (needed for 16-bit apps)
     141             :                          * Use #ifndef for big buffer version (32-bit)
     142             :                          */
     143          24 :                         if (over4k) {
     144          12 :                                 if (dbwritetext(blobproc, objname, textPtr, DBTXPLEN, timeStamp, TRUE, isiz, (BYTE*) blob) != SUCCEED)
     145             :                                         return 5;
     146             :                         } else {
     147          12 :                                 if (dbwritetext(blobproc, objname, textPtr, DBTXPLEN, timeStamp, TRUE, isiz, NULL) != SUCCEED)
     148             :                                         return 15;
     149          12 :                                 dbsqlok(blobproc);
     150          12 :                                 dbresults(blobproc);
     151             : 
     152          12 :                                 numtowrite = 0;
     153             :                                 /* Send the update value in chunks. */
     154         192 :                                 for (numwritten = 0; numwritten < isiz; numwritten += numtowrite) {
     155         180 :                                         numtowrite = (isiz - numwritten);
     156         180 :                                         if (numtowrite > BLOB_BLOCK_SIZE)
     157         168 :                                                 numtowrite = BLOB_BLOCK_SIZE;
     158         180 :                                         dbmoretext(blobproc, (DBINT) numtowrite, (BYTE *) (blob + numwritten));
     159             :                                 }
     160          12 :                                 dbsqlok(blobproc);
     161          36 :                                 while (dbresults(blobproc) != NO_MORE_RESULTS)
     162          12 :                                         continue;
     163             :                         }
     164             :                 }
     165             :         }
     166             : 
     167          12 :         printf("select\n");
     168             : 
     169          12 :         sql_cmd(dbproc);
     170          12 :         dbsqlexec(dbproc);
     171             : 
     172          12 :         if (dbresults(dbproc) != SUCCEED) {
     173           0 :                 printf("Was expecting a result set.");
     174           0 :                 exit(1);
     175             :         }
     176             : 
     177          24 :         for (i = 1; i <= dbnumcols(dbproc); i++) {
     178          24 :                 printf("col %d is %s\n", i, dbcolname(dbproc, i));
     179             :         }
     180             : 
     181          12 :         if (SUCCEED != dbbind(dbproc, 1, INTBIND, -1, (BYTE *) & testint)) {
     182           0 :                 fprintf(stderr, "Had problem with bind\n");
     183           0 :                 abort();
     184             :         }
     185             : 
     186          84 :         for (i = 0; i < rows_to_add; i++) {
     187             :                 char expected[1024];
     188             : 
     189          36 :                 sprintf(expected, "row %03d", i);
     190             : 
     191          36 :                 if (REG_ROW != dbnextrow(dbproc)) {
     192           0 :                         fprintf(stderr, "Failed.  Expected a row\n");
     193           0 :                         exit(1);
     194             :                 }
     195          36 :                 if (testint != i) {
     196           0 :                         fprintf(stderr, "Failed.  Expected i to be %d, was %d\n", i, (int) testint);
     197           0 :                         abort();
     198             :                 }
     199             : 
     200             :                 /* get the image */
     201          36 :                 strcpy(sqlCmd, "SET TEXTSIZE 2147483647");
     202          36 :                 dbcmd(blobproc, sqlCmd);
     203          36 :                 dbsqlexec(blobproc);
     204             : 
     205          36 :                 if (dbresults(blobproc) != SUCCEED) {
     206           0 :                         dbcancel(blobproc);
     207           0 :                         return 16;
     208             :                 }
     209             : 
     210          36 :                 sprintf(sqlCmd, "SELECT PigTure FROM dblib0014 WHERE i = %d", i);
     211          36 :                 dbcmd(blobproc, sqlCmd);
     212          36 :                 dbsqlexec(blobproc);
     213          36 :                 if (dbresults(blobproc) != SUCCEED) {
     214           0 :                         fprintf(stderr, "Error extracting blob\n");
     215           0 :                         return 6;
     216             :                 }
     217             : 
     218             :                 numread = 0;
     219             :                 rblob = NULL;
     220         432 :                 while ((result = dbreadtext(blobproc, rbuf, BLOB_BLOCK_SIZE)) != NO_MORE_ROWS) {
     221         396 :                         assert(result >= 0);
     222         396 :                         if (result != 0) {      /* this indicates not end of row */
     223         360 :                                 rblob = (char*) realloc(rblob, result + numread);
     224         360 :                                 assert(rblob);
     225         360 :                                 memcpy((void *) (rblob + numread), (void *) rbuf, result);
     226         360 :                                 numread += result;
     227             :                         }
     228             :                 }
     229             : 
     230             :                 /* first row is NULL */
     231          36 :                 if (rblob != NULL && i == 0) {
     232           0 :                         fputs("Blob data received\n", stderr);
     233           0 :                         return 7;
     234             :                 }
     235          36 :                 if (rblob == NULL && i > 0) {
     236           0 :                         fputs("No blob data received\n", stderr);
     237           0 :                         return 7;
     238             :                 }
     239             : 
     240          36 :                 if (i == 1) {
     241          12 :                         printf("Saving send blob data row to file: %s\n", argv[2]);
     242          12 :                         if ((fp = fopen(argv[2], "wb")) == NULL) {
     243           0 :                                 free(blob);
     244           0 :                                 free(rblob);
     245           0 :                                 fprintf(stderr, "Unable to open output file: %s\n", argv[2]);
     246           0 :                                 return 3;
     247             :                         }
     248             : 
     249          12 :                         result = (long) fwrite((void *) rblob, numread, 1, fp);
     250          12 :                         fclose(fp);
     251             :                 }
     252             : 
     253          36 :                 printf("Read blob data row %d --> %s %lu byte comparison\n",
     254          36 :                        (int) testint, (memcmp(blob, rblob, numread)) ? "failed" : "PASSED", (long unsigned int) numread);
     255          36 :                 free(rblob);
     256             :         }
     257             : 
     258          12 :         if (dbnextrow(dbproc) != NO_MORE_ROWS) {
     259           0 :                 fprintf(stderr, "Was expecting no more rows\n");
     260           0 :                 exit(1);
     261             :         }
     262             : 
     263          12 :         free(blob);
     264             : 
     265          12 :         printf("Dropping table\n");
     266          12 :         sql_cmd(dbproc);
     267          12 :         dbsqlexec(dbproc);
     268          12 :         while (dbresults(dbproc) != NO_MORE_RESULTS) {
     269             :                 /* nop */
     270             :         }
     271             : 
     272          12 :         dbexit();
     273             : 
     274          12 :         return 0;
     275             : }
     276             : 
     277          10 : TEST_MAIN()
     278             : {
     279          10 :         int res = test(argc, argv, false);
     280           6 :         if (!res)
     281           6 :                 res = test(argc, argv, true);
     282           6 :         if (res)
     283             :                 return res;
     284             : 
     285           6 :         printf("dblib okay on %s\n", __FILE__);
     286           6 :         return 0;
     287             : }
     288             : 

Generated by: LCOV version 1.13