LCOV - code coverage report
Current view: top level - src/dblib/unittests - t0016.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 145 175 82.9 %
Date: 2024-04-18 21:21:48 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /* 
       2             :  * Purpose: Test bcp in and out, and specifically bcp_colfmt()
       3             :  * Functions: bcp_colfmt bcp_columns bcp_exec bcp_init 
       4             :  */
       5             : 
       6             : #include "common.h"
       7             : 
       8             : static int failed = 0;
       9             : 
      10             : static void
      11           0 : failure(const char *fmt, ...)
      12             : {
      13             :         va_list ap;
      14             : 
      15           0 :         failed = 1;
      16             : 
      17           0 :         va_start(ap, fmt);
      18           0 :         vfprintf(stderr, fmt, ap);
      19           0 :         va_end(ap);
      20           0 : }
      21             : 
      22             : #define INFILE_NAME "t0016"
      23             : #define TABLE_NAME "#dblib0016"
      24             : 
      25             : static void test_file(const char *fn);
      26             : static int compare_files(const char *fn1, const char *fn2);
      27             : static unsigned count_file_rows(FILE *f);
      28             : static DBPROCESS *dbproc;
      29             : 
      30             : int
      31           8 : main(int argc, char *argv[])
      32             : {
      33             :         LOGINREC *login;
      34             :         char in_file[30];
      35             :         unsigned int n;
      36             : 
      37           8 :         setbuf(stdout, NULL);
      38           8 :         setbuf(stderr, NULL);
      39             : 
      40           8 :         set_malloc_options();
      41             : 
      42           8 :         read_login_info(argc, argv);
      43           8 :         printf("Starting %s\n", argv[0]);
      44           8 :         dbinit();
      45             : 
      46           8 :         dberrhandle(syb_err_handler);
      47           8 :         dbmsghandle(syb_msg_handler);
      48             : 
      49           8 :         printf("About to logon\n");
      50             : 
      51           8 :         login = dblogin();
      52           8 :         BCP_SETL(login, TRUE);
      53           8 :         DBSETLPWD(login, PASSWORD);
      54           8 :         DBSETLUSER(login, USER);
      55           8 :         DBSETLAPP(login, "t0016");
      56           8 :         DBSETLCHARSET(login, "UTF-8");
      57             : 
      58           8 :         dbproc = dbopen(login, SERVER);
      59           8 :         if (strlen(DATABASE)) {
      60           8 :                 dbuse(dbproc, DATABASE);
      61             :         }
      62           8 :         dbloginfree(login);
      63           8 :         printf("After logon\n");
      64             : 
      65           8 :         strcpy(in_file, INFILE_NAME);
      66         104 :         for (n = 1; n <= 100; ++n) {
      67         104 :                 test_file(in_file);
      68         104 :                 sprintf(in_file, "%s_%d", INFILE_NAME, n);
      69         104 :                 if (sql_reopen(in_file) != SUCCEED)
      70             :                         break;
      71             :         }
      72             : 
      73           8 :         dbclose(dbproc);
      74           8 :         dbexit();
      75             : 
      76           8 :         printf("dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
      77           8 :         return failed ? 1 : 0;
      78             : }
      79             : 
      80             : static int got_error = 0;
      81             : 
      82             : static int
      83          12 : ignore_msg_handler(DBPROCESS * dbproc, DBINT msgno, int state, int severity, char *text, char *server, char *proc, int line)
      84             : {
      85          12 :         got_error = 1;
      86          12 :         return 0;
      87             : }
      88             : 
      89             : static int
      90          12 : ignore_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
      91             : {
      92          12 :         got_error = 1;
      93          12 :         return INT_CANCEL;
      94             : }
      95             : 
      96             : static char line1[1024*16];
      97             : static char line2[1024*16];
      98             : 
      99             : static void
     100         104 : test_file(const char *fn)
     101             : {
     102             :         int i;
     103             :         RETCODE ret;
     104         104 :         int num_cols = 0;
     105         104 :         const char *out_file = "t0016.out";
     106         104 :         const char *err_file = "t0016.err";
     107             :         DBINT rows_copied;
     108         104 :         unsigned num_rows = 2;
     109             : 
     110             :         FILE *input_file;
     111             : 
     112             :         char in_file[256];
     113         104 :         snprintf(in_file, sizeof(in_file), "%s/%s.in", FREETDS_SRCDIR, fn);
     114             : 
     115         104 :         input_file = fopen(in_file, "rb");
     116         104 :         if (!input_file) {
     117           0 :                 sprintf(in_file, "%s.in", fn);
     118           0 :                 input_file = fopen(in_file, "rb");
     119             :         }
     120         104 :         if (!input_file) {
     121           0 :                 fprintf(stderr, "could not open %s\n", in_file);
     122           0 :                 exit(1);
     123             :         }
     124         104 :         num_rows = count_file_rows(input_file);
     125         104 :         fclose(input_file);
     126             : 
     127         104 :         dberrhandle(ignore_err_handler);
     128         104 :         dbmsghandle(ignore_msg_handler);
     129             : 
     130         104 :         printf("Creating table '%s'\n", TABLE_NAME);
     131         104 :         got_error = 0;
     132         104 :         sql_cmd(dbproc);
     133         104 :         dbsqlexec(dbproc);
     134         308 :         while (dbresults(dbproc) != NO_MORE_RESULTS)
     135         100 :                 continue;
     136             : 
     137         104 :         dberrhandle(syb_err_handler);
     138         104 :         dbmsghandle(syb_msg_handler);
     139             : 
     140         104 :         if (got_error)
     141          12 :                 return;
     142             : 
     143             :         /* BCP in */
     144             : 
     145          92 :         printf("bcp_init with in_file as '%s'\n", in_file);
     146          92 :         ret = bcp_init(dbproc, TABLE_NAME, in_file, err_file, DB_IN);
     147          92 :         if (ret != SUCCEED)
     148           0 :                 failure("bcp_init failed\n");
     149             : 
     150          92 :         printf("return from bcp_init = %d\n", ret);
     151             : 
     152          92 :         ret = sql_cmd(dbproc);
     153          92 :         printf("return from dbcmd = %d\n", ret);
     154             : 
     155          92 :         ret = dbsqlexec(dbproc);
     156          92 :         printf("return from dbsqlexec = %d\n", ret);
     157             : 
     158          92 :         if (dbresults(dbproc) != FAIL) {
     159          92 :                 num_cols = dbnumcols(dbproc);
     160          92 :                 printf("Number of columns = %d\n", num_cols);
     161             : 
     162          92 :                 while (dbnextrow(dbproc) != NO_MORE_ROWS) {
     163             :                 }
     164             :         }
     165             : 
     166          92 :         ret = bcp_columns(dbproc, num_cols);
     167          92 :         if (ret != SUCCEED)
     168           0 :                 failure("bcp_columns failed\n");
     169          92 :         printf("return from bcp_columns = %d\n", ret);
     170             : 
     171         554 :         for (i = 1; i < num_cols; i++) {
     172         462 :                 if ((ret = bcp_colfmt(dbproc, i, SYBCHAR, 0, -1, (const BYTE *) "\t", sizeof(char), i)) == FAIL)
     173           0 :                         failure("return from bcp_colfmt = %d\n", ret);
     174             :         }
     175             : 
     176          92 :         if ((ret = bcp_colfmt(dbproc, num_cols, SYBCHAR, 0, -1, (const BYTE *) "\n", sizeof(char), num_cols)) == FAIL)
     177           0 :                 failure("return from bcp_colfmt = %d\n", ret);
     178             : 
     179             : 
     180          92 :         ret = bcp_exec(dbproc, &rows_copied);
     181          92 :         if (ret != SUCCEED || rows_copied != num_rows)
     182           0 :                 failure("bcp_exec failed\n");
     183             : 
     184          92 :         printf("%d rows copied in\n", rows_copied);
     185             : 
     186             :         /* BCP out */
     187             : 
     188          92 :         rows_copied = 0;
     189          92 :         ret = bcp_init(dbproc, TABLE_NAME, out_file, err_file, DB_OUT);
     190          92 :         if (ret != SUCCEED)
     191           0 :                 failure("bcp_int failed\n");
     192             : 
     193          92 :         printf("select\n");
     194          92 :         sql_cmd(dbproc);
     195          92 :         dbsqlexec(dbproc);
     196             : 
     197          92 :         if (dbresults(dbproc) != FAIL) {
     198          92 :                 num_cols = dbnumcols(dbproc);
     199          92 :                 while (dbnextrow(dbproc) != NO_MORE_ROWS) {
     200             :                 }
     201             :         }
     202             : 
     203          92 :         ret = bcp_columns(dbproc, num_cols);
     204             : 
     205         554 :         for (i = 1; i < num_cols; i++) {
     206         462 :                 if ((ret = bcp_colfmt(dbproc, i, SYBCHAR, 0, -1, (const BYTE *) "\t", sizeof(char), i)) == FAIL)
     207           0 :                         failure("return from bcp_colfmt = %d\n", ret);
     208             :         }
     209             : 
     210          92 :         if ((ret = bcp_colfmt(dbproc, num_cols, SYBCHAR, 0, -1, (const BYTE *) "\n", sizeof(char), num_cols)) == FAIL)
     211           0 :                 failure("return from bcp_colfmt = %d\n", ret);
     212             : 
     213          92 :         ret = bcp_exec(dbproc, &rows_copied);
     214          92 :         if (ret != SUCCEED || rows_copied != num_rows)
     215           0 :                 failure("bcp_exec failed\n");
     216             : 
     217          92 :         printf("%d rows copied out\n", rows_copied);
     218             : 
     219          92 :         printf("Dropping table '%s'\n", TABLE_NAME);
     220          92 :         sql_cmd(dbproc);
     221          92 :         dbsqlexec(dbproc);
     222         276 :         while (dbresults(dbproc) != NO_MORE_RESULTS)
     223          92 :                 continue;
     224             : 
     225          92 :         if (failed)
     226             :                 return;
     227             : 
     228          92 :         if (compare_files(in_file, out_file))
     229          92 :                 printf("Input and output files are equal\n");
     230             :         else
     231           0 :                 failed = 1;
     232             : }
     233             : 
     234         864 : static size_t fgets_raw(char *s, int len, FILE *f)
     235             : {
     236         864 :         char *p = s;
     237             : 
     238      578620 :         while (len > 1) {
     239      577756 :                 int c = getc(f);
     240      577756 :                 if (c == EOF) {
     241         288 :                         if (ferror(f))
     242             :                                 return 0;
     243             :                         break;
     244             :                 }
     245      577468 :                 *p++ = c;
     246      577468 :                 --len;
     247      577468 :                 if (c == '\n')
     248             :                         break;
     249             :         }
     250         864 :         if (len > 0)
     251         864 :                 *p = 0;
     252         864 :         return p - s;
     253             : }
     254             : 
     255          92 : static int compare_files(const char *fn1, const char *fn2)
     256             : {
     257          92 :         int equal = 1;
     258             :         FILE *f1, *f2;
     259             :         size_t s1, s2;
     260             : 
     261             :         /* check input and output should be the same */
     262          92 :         f1 = fopen(fn1, "r");
     263          92 :         f2 = fopen(fn2, "r");
     264          92 :         if (f1 != NULL && f2 != NULL) {
     265             :                 int line = 1;
     266             : 
     267         184 :                 for (;; ++line) {
     268         460 :                         s1 = fgets_raw(line1, sizeof(line1), f1);
     269         276 :                         s2 = fgets_raw(line2, sizeof(line2), f2);
     270             : 
     271             :                         /* EOF or error of one */
     272         276 :                         if (!!s1 != !!s2) {
     273           0 :                                 equal = 0;
     274           0 :                                 failure("error reading a file or EOF of a file\n");
     275           0 :                                 break;
     276             :                         }
     277             : 
     278             :                         /* EOF or error of both */
     279         276 :                         if (!s1) {
     280          92 :                                 if (feof(f1) && feof(f2))
     281             :                                         break;
     282           0 :                                 equal = 0;
     283           0 :                                 failure("error reading a file\n");
     284           0 :                                 break;
     285             :                         }
     286             : 
     287         184 :                         if (s1 != s2 || memcmp(line1, line2, s1) != 0) {
     288           0 :                                 equal = 0;
     289           0 :                                 failure("File different at line %d\n"
     290             :                                         " input: %s"
     291             :                                         " output: %s",
     292             :                                         line, line1, line2);
     293             :                         }
     294             :                 }
     295             :         } else {
     296           0 :                 equal = 0;
     297           0 :                 failure("error opening files\n");
     298             :         }
     299          92 :         if (f1)
     300          92 :                 fclose(f1);
     301          92 :         if (f2)
     302          92 :                 fclose(f2);
     303             : 
     304          92 :         return equal;
     305             : }
     306             : 
     307         104 : static unsigned count_file_rows(FILE *f)
     308             : {
     309             :         size_t s;
     310         104 :         unsigned rows = 1;
     311         104 :         char last = '\n';
     312             : 
     313         104 :         assert(f);
     314             : 
     315         312 :         while ((s = fgets_raw(line1, sizeof(line1), f)) != 0) {
     316         208 :                 last = line1[s-1];
     317         208 :                 if (last == '\n')
     318         208 :                         ++rows;
     319             :         }
     320         104 :         if (last == '\n')
     321         104 :                 --rows;
     322         104 :         assert(!ferror(f));
     323         104 :         return rows;
     324             : }

Generated by: LCOV version 1.13