LCOV - code coverage report
Current view: top level - src/tds/unittests - allcolumns.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 166 171 97.1 %
Date: 2025-02-21 09:36:06 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns
       3             :  * Copyright (C) 2017  Frediano Ziglio
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or
       6             :  * modify it under the terms of the GNU Library General Public
       7             :  * License as published by the Free Software Foundation; either
       8             :  * version 2 of the License, or (at your option) any later version.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :  * Library General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU Library General Public
      16             :  * License along with this library; if not, write to the
      17             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      18             :  * Boston, MA 02111-1307, USA.
      19             :  */
      20             : 
      21             : #define TDS_DONT_DEFINE_DEFAULT_FUNCTIONS
      22             : #include "common.h"
      23             : #include <assert.h>
      24             : #include <freetds/convert.h>
      25             : #include <freetds/checks.h>
      26             : 
      27             : static bool
      28        4230 : is_convert_pointer_type(int type)
      29             : {
      30        4230 :         switch (type) {
      31             :         case SYBCHAR: case SYBVARCHAR: case SYBTEXT: case XSYBCHAR: case XSYBVARCHAR:
      32             :         case SYBBINARY: case SYBVARBINARY: case SYBIMAGE: case XSYBBINARY: case XSYBVARBINARY:
      33             :         case SYBLONGBINARY:
      34             :                 return true;
      35             :         }
      36        3660 :         return false;
      37             : }
      38             : 
      39             : 
      40             : static void
      41        2160 : free_convert(int type, CONV_RESULT *cr)
      42             : {
      43        2160 :         if (is_convert_pointer_type(type))
      44         330 :                 free(cr->c);
      45        2160 : }
      46             : 
      47             : static void create_type(TDSSOCKET *tds, int desttype, int server_type, tds_any_type_t *func);
      48             : 
      49             : enum { TDSVER_MS = 0x704, TDSVER_SYB = 0x500 };
      50             : 
      51          30 : void tds_all_types(TDSSOCKET *tds, tds_any_type_t *func)
      52             : {
      53             :         int desttype;
      54             : 
      55          30 :         tds->conn->tds_version = TDSVER_MS;
      56             : 
      57             :         /*
      58             :          * Test every type
      59             :          */
      60        7710 :         for (desttype = 0; desttype < 0x100; desttype++) {
      61             :                 int types_buffer[10];
      62        7680 :                 int *types = types_buffer, *types_end;
      63             :                 int server_type;
      64             :                 int varint, other_varint;
      65             : 
      66        7680 :                 if (!is_tds_type_valid(desttype))
      67       12240 :                         continue;
      68             : 
      69        1740 :                 tds->conn->tds_version = TDSVER_MS;
      70             : 
      71             :                 /* if is only Sybase change version to Sybase */
      72        1740 :                 varint = tds_get_varint_size(tds->conn, desttype);
      73        1740 :                 tds->conn->tds_version ^= TDSVER_MS ^ TDSVER_SYB;
      74        1740 :                 other_varint = tds_get_varint_size(tds->conn, desttype);
      75        1740 :                 tds->conn->tds_version ^= TDSVER_MS ^ TDSVER_SYB;
      76        1740 :                 if (varint == 1 && varint != other_varint)
      77         360 :                         tds->conn->tds_version = TDSVER_SYB;
      78             : 
      79        1740 :                 server_type = desttype;
      80        1740 :                 switch (desttype) {
      81             :                 /* unsupported */
      82          60 :                 case SYBVOID:
      83             :                 case SYBINTERVAL:
      84          60 :                         continue;
      85             :                 /* nullable, use another type */
      86             :                 /* TODO, try all sizes */
      87          30 :                 case SYBINTN:
      88          30 :                         *types++ = SYBINT1;
      89          30 :                         *types++ = SYBINT2;
      90          30 :                         *types++ = SYBINT4;
      91          30 :                         *types++ = SYBINT8;
      92          30 :                         break;
      93          30 :                 case SYBUINTN:
      94          30 :                         *types++ = SYBUINT1;
      95          30 :                         *types++ = SYBUINT2;
      96          30 :                         *types++ = SYBUINT4;
      97          30 :                         *types++ = SYBUINT8;
      98          30 :                         tds->conn->tds_version = TDSVER_SYB;
      99          30 :                         break;
     100          30 :                 case SYBFLTN:
     101          30 :                         *types++ = SYBREAL;
     102          30 :                         *types++ = SYBFLT8;
     103          30 :                         break;
     104          30 :                 case SYBMONEYN:
     105          30 :                         *types++ = SYBMONEY4;
     106          30 :                         *types++ = SYBMONEY;
     107          30 :                         break;
     108          30 :                 case SYBDATETIMN:
     109          30 :                         *types++ = SYBDATETIME4;
     110          30 :                         *types++ = SYBDATETIME;
     111          30 :                         break;
     112          30 :                 case SYBDATEN:
     113          30 :                         *types++ = SYBDATE;
     114          30 :                         tds->conn->tds_version = TDSVER_SYB;
     115          30 :                         break;
     116          30 :                 case SYBTIMEN:
     117          30 :                         *types++ = SYBTIME;
     118          30 :                         tds->conn->tds_version = TDSVER_SYB;
     119          30 :                         break;
     120          30 :                 case SYB5INT8:
     121          30 :                         *types++ = SYBINT8;
     122          30 :                         break;
     123             :                 /* TODO tds_set_column_type */
     124             : 
     125         300 :                 case SYBXML: /* ?? */
     126             :                 case SYBNTEXT: /* ?? */
     127             :                 case XSYBNVARCHAR:
     128             :                 case XSYBNCHAR:
     129             :                 case SYBNVARCHAR:
     130             :                 case SYBMSUDT:
     131             :                 case SYBMSXML:
     132             :                 case SYBUNITEXT:
     133             :                 case SYBVARIANT: /* TODO */
     134             :                 case SYBSINT1: /* TODO */
     135             :                 case SYBMSTABLE: /* TODO */
     136         300 :                         continue;
     137             :                 }
     138             : 
     139        1380 :                 if (types == types_buffer)
     140        1140 :                         *types++ = desttype;
     141             : 
     142        1380 :                 types_end = types;
     143        3030 :                 for (types = types_buffer; types != types_end; ++types) {
     144        1650 :                         create_type(tds, *types, server_type, func);
     145        1650 :                         if (*types != server_type)
     146         510 :                                 create_type(tds, *types, *types, func);
     147             :                 }
     148             :         }
     149          30 : }
     150             : 
     151        2160 : static void create_type(TDSSOCKET *tds, int desttype, int server_type, tds_any_type_t *func)
     152             : {
     153        2160 :         const TDSCONTEXT *ctx = tds_get_ctx(tds);
     154             :         int result;
     155        2160 :         TDS_CHAR *src = NULL;
     156             :         TDS_UINT srclen;
     157             : 
     158             :         CONV_RESULT cr;
     159        2160 :         const int srctype = SYBCHAR;
     160             : 
     161             :         TDSRESULTINFO *results;
     162             :         TDSCOLUMN *curcol;
     163             : 
     164        2160 :         cr.n.precision = 8;
     165        2160 :         cr.n.scale = 2;
     166             : 
     167        2160 :         switch (desttype) {
     168             :         case SYBCHAR:
     169             :         case SYBVARCHAR:
     170             :         case SYBTEXT:
     171             :         case XSYBVARCHAR:
     172             :         case XSYBCHAR:
     173             :                 src = "test of a character field";
     174             :                 break;
     175         180 :         case SYBDATETIME:
     176             :         case SYBDATETIME4:
     177         180 :                 src = "Apr 12, 1985 17:49:41";
     178         180 :                 break;
     179         120 :         case SYBMSDATE:
     180             :         case SYBDATE:
     181         120 :                 src = "2012-11-27";
     182         120 :                 break;
     183          90 :         case SYBTIME:
     184          90 :                 src = "15:27:12";
     185          90 :                 break;
     186          60 :         case SYBMSTIME:
     187             :         case SYB5BIGTIME:
     188          60 :                 src = "15:27:12.327862";
     189          60 :                 break;
     190          90 :         case SYBMSDATETIME2:
     191             :         case SYBMSDATETIMEOFFSET:
     192             :         case SYB5BIGDATETIME:
     193          90 :                 src = "2015-09-12 21:48:12.638161";
     194          90 :                 break;
     195          60 :         case SYBBINARY:
     196             :         case SYBIMAGE:
     197          60 :                 src = "0xbeef";
     198          60 :                 break;
     199         540 :         case SYBINT1:
     200             :         case SYBINT2:
     201             :         case SYBINT4:
     202             :         case SYBUINT1:
     203             :         case SYBUINT2:
     204             :         case SYBUINT4:
     205         540 :                 src = "255";
     206         540 :                 break;
     207         240 :         case SYBINT8:
     208             :         case SYBUINT8:
     209         240 :                 src = "374632567765";
     210         240 :                 break;
     211         360 :         case SYBFLT8:
     212             :         case SYBREAL:
     213             :         case SYBMONEY:
     214             :         case SYBMONEY4:
     215         360 :                 src = "1237.45";
     216             :                 cr.n.precision = 8;
     217             :                 cr.n.scale = 2;
     218         360 :                 break;
     219          60 :         case SYBNUMERIC:
     220             :         case SYBDECIMAL:
     221          60 :                 src = "947919.25";
     222             :                 cr.n.precision = 8;
     223             :                 cr.n.scale = 2;
     224          60 :                 break;
     225          30 :         case SYBUNIQUE:
     226          30 :                 src = "A8C60F70-5BD4-3E02-B769-7CCCCA585DCC";
     227          30 :                 break;
     228         180 :         case SYBBIT:
     229             :         default:
     230         180 :                 src = "1";
     231         180 :                 break;
     232             :         }
     233             :         assert(src);
     234        2160 :         srclen = strlen(src);
     235             : 
     236             :         /*
     237             :          * Now at last do the conversion
     238             :          */
     239             : 
     240        2160 :         result = tds_convert(ctx, srctype, src, srclen, desttype, &cr);
     241             : 
     242        2160 :         if (result < 0) {
     243           0 :                 if (result == TDS_CONVERT_NOAVAIL)      /* tds_willconvert returned true, but it lied. */
     244           0 :                         fprintf(stderr, "Conversion not yet implemented:\n\t");
     245             : 
     246           0 :                 fprintf(stderr, "failed (%d) to convert %d (%s, %d bytes) : %d (%s).\n",
     247             :                         result,
     248             :                         srctype, tds_prtype(srctype), srclen,
     249             :                         desttype, tds_prtype(desttype));
     250             : 
     251           0 :                 if (result == TDS_CONVERT_NOAVAIL)
     252           0 :                         exit(1);
     253             :         }
     254             : 
     255        2160 :         printf("converted %d (%s, %d bytes) -> %d (%s, %d bytes).\n",
     256             :                srctype, tds_prtype(srctype), srclen,
     257             :                desttype, tds_prtype(desttype), result);
     258             : 
     259        2160 :         results = tds_alloc_param_result(NULL);
     260        2160 :         assert(results);
     261        2160 :         curcol = results->columns[0];
     262        2160 :         assert(curcol);
     263             : 
     264        2160 :         tds_set_column_type(tds->conn, curcol, server_type);
     265        2160 :         curcol->on_server.column_size = curcol->column_size = curcol->column_cur_size = result;
     266        2160 :         if (is_numeric_type(desttype)) {
     267          60 :                 curcol->column_prec = cr.n.precision;
     268          60 :                 curcol->column_scale = cr.n.scale;
     269             :         }
     270        2160 :         switch (desttype) {
     271          60 :         case SYB5BIGDATETIME:
     272             :         case SYB5BIGTIME:
     273          60 :                 curcol->column_prec = curcol->column_scale = 6;
     274          60 :                 break;
     275             :         }
     276        2160 :         CHECK_COLUMN_EXTRA(curcol);
     277             : 
     278        2160 :         tds_alloc_param_data(curcol);
     279        2160 :         if (is_blob_col(curcol)) {
     280          90 :                 ((TDSBLOB *) curcol->column_data)->textvalue = cr.c;
     281          90 :                 cr.c = NULL;
     282        2070 :         } else if (is_convert_pointer_type(desttype)) {
     283         240 :                 memcpy(curcol->column_data, cr.c, result);
     284             :         } else {
     285        1830 :                 memcpy(curcol->column_data, &cr.i, result);
     286             :         }
     287             : 
     288        2160 :         func(tds, curcol);
     289             : 
     290             :         /* try to convert to SQL_VARIANT */
     291        2160 :         if (is_variant_inner_type(desttype)) {
     292             :                 TDSVARIANT *v;
     293             :                 TDSCOLUMN *basecol;
     294             : 
     295        1470 :                 tds->conn->tds_version = TDSVER_MS;
     296             : 
     297        1470 :                 results = tds_alloc_param_result(results);
     298        1470 :                 assert(results);
     299             : 
     300        1470 :                 basecol = results->columns[0];
     301        1470 :                 curcol = results->columns[1];
     302        1470 :                 tds_set_column_type(tds->conn, curcol, SYBVARIANT);
     303        1470 :                 CHECK_COLUMN_EXTRA(curcol);
     304             : 
     305        1470 :                 tds_alloc_param_data(curcol);
     306        1470 :                 v = (TDSVARIANT *) curcol->column_data;
     307        1470 :                 v->size = basecol->column_size;
     308        1470 :                 v->type = basecol->column_type;
     309        1470 :                 memcpy(v->collation, basecol->column_collation, sizeof(v->collation));
     310             : 
     311        1470 :                 assert(basecol->column_cur_size > 0);
     312        1470 :                 v->data = tds_new(TDS_CHAR, basecol->column_cur_size);
     313        1470 :                 assert(v->data);
     314        1470 :                 v->data_len = basecol->column_cur_size;
     315        1470 :                 curcol->column_cur_size = v->data_len;
     316        1470 :                 curcol->column_size = curcol->on_server.column_size = 8009;
     317        1470 :                 assert(!is_blob_col(basecol));
     318        1470 :                 memcpy(v->data, basecol->column_data, v->data_len);
     319        1470 :                 CHECK_COLUMN_EXTRA(curcol);
     320             : 
     321        1470 :                 func(tds, curcol);
     322             :         }
     323             : 
     324        2160 :         tds_free_results(results);
     325             : 
     326        2160 :         if (result >= 0)
     327        2160 :                 free_convert(desttype, &cr);
     328        2160 : }

Generated by: LCOV version 1.13