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 : *
4 : * This library is free software; you can redistribute it and/or
5 : * modify it under the terms of the GNU Library General Public
6 : * License as published by the Free Software Foundation; either
7 : * version 2 of the License, or (at your option) any later version.
8 : *
9 : * This library is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : * Library General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU Library General Public
15 : * License along with this library; if not, write to the
16 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 : * Boston, MA 02111-1307, USA.
18 : */
19 :
20 : /*
21 : * Test data from server
22 : * The test do a select for a given type, convert to char and compare result
23 : */
24 : #include "common.h"
25 :
26 : #include <assert.h>
27 : #include <freetds/convert.h>
28 :
29 : static int g_result = 0;
30 : static TDSLOGIN *login;
31 : static TDSSOCKET *tds;
32 :
33 : static void test0(const char *type, ...);
34 :
35 : static void
36 : test(const char *type, const char *value, const char *result)
37 : {
38 230 : test0(type, value, result, NULL);
39 : }
40 :
41 : static void
42 762 : exec_query(const char *query)
43 : {
44 762 : if (tds_submit_query(tds, query) != TDS_SUCCESS || tds_process_simple_query(tds) != TDS_SUCCESS) {
45 0 : fprintf(stderr, "executing query failed\n");
46 0 : exit(1);
47 : }
48 762 : }
49 :
50 : static void
51 246 : test0(const char *type, ...)
52 : {
53 : char buf[512];
54 : CONV_RESULT cr;
55 : int rc;
56 : TDS_INT result_type;
57 : int done_flags;
58 : va_list ap;
59 : struct {
60 : const char *value;
61 : const char *result;
62 : } data[10];
63 246 : int num_data = 0, i_row;
64 :
65 246 : sprintf(buf, "CREATE TABLE #tmp(a %s)", type);
66 246 : exec_query(buf);
67 :
68 246 : va_start(ap, type);
69 270 : for (;;) {
70 516 : const char * value = va_arg(ap, const char *);
71 : const char * result;
72 516 : if (!value)
73 : break;
74 270 : result = va_arg(ap, const char *);
75 270 : if (!result)
76 120 : result = value;
77 : data[num_data].value = value;
78 270 : data[num_data].result = result;
79 270 : sprintf(buf, "INSERT INTO #tmp VALUES(CONVERT(%s,'%s'))", type, value);
80 270 : exec_query(buf);
81 270 : ++num_data;
82 : }
83 246 : va_end(ap);
84 :
85 246 : assert(num_data > 0);
86 :
87 : /* execute it */
88 246 : rc = tds_submit_query(tds, "SELECT * FROM #tmp");
89 246 : if (rc != TDS_SUCCESS) {
90 0 : fprintf(stderr, "tds_submit_query() failed\n");
91 0 : exit(1);
92 : }
93 :
94 246 : if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCESS) {
95 0 : fprintf(stderr, "tds_process_tokens() failed\n");
96 0 : exit(1);
97 : }
98 :
99 246 : if (result_type != TDS_ROWFMT_RESULT) {
100 0 : fprintf(stderr, "expected row fmt() failed\n");
101 0 : exit(1);
102 : }
103 :
104 246 : if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCESS) {
105 0 : fprintf(stderr, "tds_process_tokens() failed\n");
106 0 : exit(1);
107 : }
108 :
109 246 : if (result_type != TDS_ROW_RESULT) {
110 0 : fprintf(stderr, "expected row result() failed\n");
111 0 : exit(1);
112 : }
113 :
114 : i_row = 0;
115 516 : while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCESS && (result_type == TDS_ROW_RESULT || result_type == TDS_COMPUTE_RESULT)) {
116 :
117 270 : TDSCOLUMN *curcol = tds->current_results->columns[0];
118 270 : TDS_CHAR *src = (TDS_CHAR *) curcol->column_data;
119 270 : int conv_type = tds_get_conversion_type(curcol->column_type, curcol->column_size);
120 :
121 270 : assert(i_row < num_data);
122 :
123 270 : if (is_blob_col(curcol) && curcol->column_type != SYBVARIANT) {
124 46 : TDSBLOB *blob = (TDSBLOB *) src;
125 :
126 46 : src = blob->textvalue;
127 : }
128 :
129 270 : if (tds_convert(test_context, conv_type, src, curcol->column_cur_size, SYBVARCHAR, &cr) < 0) {
130 0 : fprintf(stderr, "Error converting\n");
131 0 : g_result = 1;
132 : } else {
133 270 : if (strcmp(data[i_row].result, cr.c) != 0) {
134 0 : fprintf(stderr, "Failed! Is \n%s\nShould be\n%s\n", cr.c, data[i_row].result);
135 0 : g_result = 1;
136 : }
137 270 : free(cr.c);
138 : }
139 270 : ++i_row;
140 : }
141 :
142 246 : if (rc != TDS_NO_MORE_RESULTS && rc != TDS_SUCCESS) {
143 0 : fprintf(stderr, "tds_process_tokens() unexpected return\n");
144 0 : exit(1);
145 : }
146 :
147 246 : while ((rc = tds_process_tokens(tds, &result_type, &done_flags, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) {
148 0 : switch (result_type) {
149 : case TDS_NO_MORE_RESULTS:
150 0 : return;
151 :
152 0 : case TDS_DONE_RESULT:
153 : case TDS_DONEPROC_RESULT:
154 : case TDS_DONEINPROC_RESULT:
155 0 : if (!(done_flags & TDS_DONE_ERROR))
156 : break;
157 :
158 : default:
159 0 : fprintf(stderr, "tds_process_tokens() unexpected result_type\n");
160 0 : exit(1);
161 : break;
162 : }
163 0 : }
164 :
165 246 : exec_query("DROP TABLE #tmp");
166 : }
167 :
168 : int
169 8 : main(int argc, char **argv)
170 : {
171 8 : printf("%s: Testing conversion from server\n", __FILE__);
172 8 : if (try_tds_login(&login, &tds, __FILE__, 0) != TDS_SUCCESS) {
173 0 : fprintf(stderr, "try_tds_login() failed\n");
174 0 : return 1;
175 : }
176 :
177 : /* bit */
178 8 : test("BIT", "0", NULL);
179 8 : test("BIT", "1", NULL);
180 :
181 : /* integers */
182 8 : test("TINYINT", "234", NULL);
183 8 : test("SMALLINT", "-31789", NULL);
184 8 : test("INT", "16909060", NULL);
185 :
186 : /* floating point */
187 8 : test("REAL", "1.25", NULL);
188 8 : test("FLOAT", "-49586.345", "-49586.345000000001");
189 :
190 : /* money */
191 8 : test("MONEY", "-123.3400", "-123.3400");
192 8 : test("MONEY", "-123.3450", "-123.3450");
193 8 : test("MONEY", "123.3450", "123.3450");
194 : /* very long money, this test int64 operations too */
195 8 : test("MONEY", "123456789012345.67", "123456789012345.6700");
196 : /* test smaller money */
197 8 : test("MONEY", "-922337203685477.5808", "-922337203685477.5808");
198 8 : test("SMALLMONEY", "89123.12", "89123.1200");
199 8 : test("SMALLMONEY", "-123.3400", "-123.3400");
200 8 : test("SMALLMONEY", "-123.3450", "-123.3450");
201 8 : test("SMALLMONEY", "123.3450", "123.3450");
202 : /* test smallest smallmoney */
203 8 : test("SMALLMONEY", "-214748.3648", "-214748.3648");
204 :
205 : /* char */
206 8 : test("CHAR(10)", "pippo", "pippo ");
207 8 : test("VARCHAR(20)", "pippo", NULL);
208 8 : test0("TEXT", "a", NULL, "foofoo", NULL, "try with a relatively long value, we hope for the best", NULL, NULL);
209 :
210 : /* binary */
211 8 : test("VARBINARY(6)", "foo", "666f6f");
212 8 : test("BINARY(6)", "foo", "666f6f000000");
213 8 : test0("IMAGE", "foo", "666f6f", "foofoofoofoo", "666f6f666f6f666f6f666f6f", NULL);
214 :
215 : /* numeric */
216 8 : test("NUMERIC(10,2)", "12765.76", NULL);
217 8 : test("NUMERIC(18,4)", "12765.761234", "12765.7612");
218 :
219 : /* date */
220 8 : free(test_context->locale->datetime_fmt);
221 8 : test_context->locale->datetime_fmt = strdup("%Y-%m-%d %H:%M:%S");
222 8 : free(test_context->locale->date_fmt);
223 8 : test_context->locale->date_fmt = strdup("%Y-%m-%d");
224 8 : free(test_context->locale->time_fmt);
225 8 : test_context->locale->time_fmt = strdup("%H:%M:%S");
226 :
227 8 : test("DATETIME", "2003-04-21 17:50:03", NULL);
228 8 : test("SMALLDATETIME", "2003-04-21 17:50:03", "2003-04-21 17:50:00");
229 :
230 8 : if (IS_TDS7_PLUS(tds->conn)) {
231 6 : test("UNIQUEIDENTIFIER", "12345678-1234-A234-9876-543298765432", NULL);
232 6 : test("NVARCHAR(20)", "Excellent test", NULL);
233 6 : test("NCHAR(20)", "Excellent test", "Excellent test ");
234 : test("NTEXT", "Excellent test", NULL);
235 : }
236 :
237 8 : if (IS_TDS71_PLUS(tds->conn)) {
238 : test("SQL_VARIANT", "test123", NULL);
239 : }
240 :
241 8 : try_tds_logout(login, tds, 0);
242 8 : return g_result;
243 : }
|