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) 2010 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 : #include "common.h"
21 :
22 : #include <ctype.h>
23 : #include <assert.h>
24 :
25 : static TDSSOCKET *tds;
26 :
27 : /* Some no-ASCII strings (XML coding) */
28 : static const char english[] = "English";
29 : static const char spanish[] = "Español";
30 : static const char french[] = "Français";
31 : static const char portuguese[] = "Português";
32 : static const char russian[] = "Русский";
33 : static const char arabic[] = "العربية";
34 : static const char chinese[] = "简体中文";
35 : static const char japanese[] = "日本語";
36 : static const char hebrew[] = "עברית";
37 :
38 : static const char *strings[] = {
39 : english,
40 : spanish,
41 : french,
42 : portuguese,
43 : russian,
44 : arabic,
45 : chinese,
46 : japanese,
47 : hebrew,
48 : NULL, /* will be replaced with large data */
49 : NULL, /* will be replaced with large data */
50 : NULL, /* will be replaced with large data */
51 : NULL, /* will be replaced with large data */
52 : NULL
53 : };
54 :
55 : static void
56 270 : query(const char *sql)
57 : {
58 270 : if (run_query(tds, sql) != TDS_SUCCESS) {
59 0 : fprintf(stderr, "error executing query: %s\n", sql);
60 0 : exit(1);
61 : }
62 270 : }
63 :
64 : static void
65 18 : test(const char *type, const char *test_name)
66 : {
67 : char buf[256];
68 : char tmp[256];
69 : int i;
70 : const char **s;
71 : int rc;
72 : TDS_INT result_type;
73 : int done_flags;
74 :
75 18 : sprintf(buf, "CREATE TABLE #tmp (i INT, t %s)", type);
76 18 : query(buf);
77 :
78 : /* insert all test strings in table */
79 252 : for (i = 0, s = strings; *s; ++s, ++i) {
80 234 : sprintf(buf, "insert into #tmp values(%d, N'%s')", i, to_utf8(*s, tmp));
81 234 : query(buf);
82 : }
83 :
84 : /* do a select and check all results */
85 18 : rc = tds_submit_query(tds, "select t from #tmp order by i");
86 18 : if (rc != TDS_SUCCESS) {
87 0 : fprintf(stderr, "tds_submit_query() failed\n");
88 0 : exit(1);
89 : }
90 :
91 18 : if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCESS) {
92 0 : fprintf(stderr, "tds_process_tokens() failed\n");
93 0 : exit(1);
94 : }
95 :
96 18 : if (result_type != TDS_ROWFMT_RESULT) {
97 0 : fprintf(stderr, "expected row fmt() failed\n");
98 0 : exit(1);
99 : }
100 :
101 18 : if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCESS) {
102 0 : fprintf(stderr, "tds_process_tokens() failed\n");
103 0 : exit(1);
104 : }
105 :
106 18 : if (result_type != TDS_ROW_RESULT) {
107 0 : fprintf(stderr, "expected row result() failed\n");
108 0 : exit(1);
109 : }
110 :
111 : i = 0;
112 252 : while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_RETURN_ROWFMT|TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCESS) {
113 :
114 234 : switch (result_type) {
115 234 : case TDS_ROW_RESULT: {
116 234 : TDSCOLUMN *curcol = tds->current_results->columns[0];
117 234 : char *src = (char *) curcol->column_data;
118 :
119 234 : if (is_blob_col(curcol)) {
120 78 : TDSBLOB *blob = (TDSBLOB *) src;
121 :
122 78 : src = blob->textvalue;
123 : }
124 :
125 234 : strcpy(buf, to_utf8(strings[i], tmp));
126 :
127 234 : if (strlen(buf) != curcol->column_cur_size || strncmp(buf, src, curcol->column_cur_size) != 0) {
128 0 : int l = curcol->column_cur_size;
129 :
130 0 : if (l > 200)
131 0 : l = 200;
132 0 : strncpy(tmp, src, l);
133 0 : tmp[l] = 0;
134 0 : fprintf(stderr, "Wrong result in test %s\n Got: '%s' len %d\n Expected: '%s' len %u\n", test_name, tmp,
135 0 : curcol->column_cur_size, buf, (unsigned int) strlen(buf));
136 0 : exit(1);
137 : }
138 234 : ++i;
139 234 : } break;
140 0 : default:
141 0 : fprintf(stderr, "Unexpected result\n");
142 0 : exit(1);
143 : break;
144 : }
145 : }
146 :
147 18 : if (rc != TDS_NO_MORE_RESULTS) {
148 0 : fprintf(stderr, "tds_process_tokens() unexpected return\n");
149 0 : exit(1);
150 : }
151 :
152 18 : while ((rc = tds_process_tokens(tds, &result_type, &done_flags, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) {
153 0 : switch (result_type) {
154 : case TDS_NO_MORE_RESULTS:
155 0 : return;
156 :
157 0 : case TDS_DONE_RESULT:
158 : case TDS_DONEPROC_RESULT:
159 : case TDS_DONEINPROC_RESULT:
160 0 : if (!(done_flags & TDS_DONE_ERROR))
161 : break;
162 :
163 : default:
164 0 : fprintf(stderr, "tds_process_tokens() unexpected result_type\n");
165 0 : exit(1);
166 : break;
167 : }
168 0 : }
169 :
170 18 : query("DROP TABLE #tmp");
171 :
172 : /* do sone select to test results */
173 : /*
174 : * for (s = strings; *s; ++s) {
175 : * printf("%s\n", to_utf8(*s, tmp));
176 : * }
177 : */
178 : }
179 :
180 : int
181 8 : main(int argc, char **argv)
182 : {
183 : TDSLOGIN *login;
184 : int ret;
185 8 : int verbose = 0;
186 :
187 : /* use UTF-8 as our coding */
188 8 : strcpy(CHARSET, "UTF-8");
189 :
190 8 : ret = try_tds_login(&login, &tds, __FILE__, verbose);
191 8 : if (ret != TDS_SUCCESS) {
192 0 : fprintf(stderr, "try_tds_login() failed\n");
193 0 : return 1;
194 : }
195 :
196 8 : if (IS_TDS7_PLUS(tds->conn)) {
197 : char type[32];
198 : char buf[1024];
199 : int i, len;
200 :
201 6 : strcpy(buf, "aaa");
202 6 : len = 0;
203 144 : for (i = 0; strlen(buf) < 980 && len < 200; ++i) {
204 : char tmp[256];
205 :
206 138 : strcat(buf, japanese);
207 138 : len += strlen(to_utf8(japanese, tmp));
208 : }
209 6 : strings[TDS_VECTOR_SIZE(strings) - 5] = buf + 3;
210 6 : strings[TDS_VECTOR_SIZE(strings) - 4] = buf + 2;
211 6 : strings[TDS_VECTOR_SIZE(strings) - 3] = buf + 1;
212 6 : strings[TDS_VECTOR_SIZE(strings) - 2] = buf;
213 :
214 6 : test("NVARCHAR(500)", "NVARCHAR with large size");
215 :
216 6 : sprintf(type, "NVARCHAR(%d)", utf8_max_len);
217 6 : test(type, "NVARCHAR with sufficient size");
218 :
219 6 : test("NTEXT", "TEXT");
220 :
221 : /* TODO test parameters */
222 : }
223 :
224 8 : try_tds_logout(login, tds, verbose);
225 8 : return 0;
226 : }
|