LCOV - code coverage report
Current view: top level - src/dblib/unittests - t0013.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 128 168 76.2 %
Date: 2025-04-25 08:22:23 Functions: 3 3 100.0 %

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

Generated by: LCOV version 1.13