1 /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  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 <freetds/utils/string.h>
23 #include <freetds/replacements.h>
24 #include <ctype.h>
25 #include <assert.h>
26 
27 static TDSSOCKET *tds;
28 
29 static void
test(const char * buf)30 test(const char *buf)
31 {
32 	char query[1024];
33 	char tmp[129 * 3];
34 	int i;
35 	int rc;
36 	TDS_INT result_type;
37 	int done_flags;
38 
39 	to_utf8(buf, tmp);
40 	sprintf(query, "SELECT 1 AS [%s]", tmp);
41 
42 	/* do a select and check all results */
43 	rc = tds_submit_query(tds, query);
44 	if (rc != TDS_SUCCESS) {
45 		fprintf(stderr, "tds_submit_query() failed\n");
46 		exit(1);
47 	}
48 
49 	if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCESS) {
50 		fprintf(stderr, "tds_process_tokens() failed\n");
51 		exit(1);
52 	}
53 
54 	if (result_type != TDS_ROWFMT_RESULT) {
55 		fprintf(stderr, "expected row fmt() failed\n");
56 		exit(1);
57 	}
58 
59 	if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCESS) {
60 		fprintf(stderr, "tds_process_tokens() failed\n");
61 		exit(1);
62 	}
63 
64 	if (result_type != TDS_ROW_RESULT) {
65 		fprintf(stderr, "expected row result() failed\n");
66 		exit(1);
67 	}
68 
69 	i = 0;
70 	while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_STOPAT_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCESS) {
71 
72 		TDSCOLUMN *curcol;
73 
74 		if (result_type != TDS_ROW_RESULT)
75 			break;
76 
77 		curcol = tds->current_results->columns[0];
78 
79 		if (strcmp(tmp, tds_dstr_cstr(&curcol->column_name)) != 0) {
80 			strlcpy(query, tds_dstr_cstr(&curcol->column_name), sizeof(query));
81 			fprintf(stderr, "Wrong result Got: '%s' len %u\n        Expected: '%s' len %u\n", query,
82 				(unsigned) tds_dstr_len(&curcol->column_name), tmp, (unsigned int) strlen(tmp));
83 			exit(1);
84 		}
85 		++i;
86 	}
87 
88 	if (rc != TDS_SUCCESS || result_type == TDS_ROW_RESULT || result_type == TDS_COMPUTE_RESULT) {
89 		fprintf(stderr, "tds_process_tokens() unexpected return\n");
90 		exit(1);
91 	}
92 
93 	while ((rc = tds_process_tokens(tds, &result_type, &done_flags, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) {
94 		switch (result_type) {
95 		case TDS_NO_MORE_RESULTS:
96 			return;
97 
98 		case TDS_DONE_RESULT:
99 		case TDS_DONEPROC_RESULT:
100 		case TDS_DONEINPROC_RESULT:
101 			if (!(done_flags & TDS_DONE_ERROR))
102 				break;
103 
104 		default:
105 			fprintf(stderr, "tds_proces_tokens() unexpected result_type\n");
106 			exit(1);
107 			break;
108 		}
109 	}
110 }
111 
112 int
main(int argc,char ** argv)113 main(int argc, char **argv)
114 {
115 	TDSLOGIN *login;
116 	int ret;
117 	int verbose = 0;
118 
119 	/* use UTF-8 as our coding */
120 	strcpy(CHARSET, "UTF-8");
121 
122 	ret = try_tds_login(&login, &tds, __FILE__, verbose);
123 	if (ret != TDS_SUCCESS) {
124 		fprintf(stderr, "try_tds_login() failed\n");
125 		return 1;
126 	}
127 
128 	if (IS_TDS7_PLUS(tds->conn)) {
129 		char buf[129 * 8];
130 		int i;
131 
132 		/* build a string of length 128 */
133 		strcpy(buf, "");
134 		for (i = 1; i <= 128; ++i) {
135 			sprintf(strchr(buf, 0), "&#x%04x;", 0x4000 + i);
136 		}
137 
138 		/* do all test */
139 		for (i = 1;;) {
140 			printf("Testing len %d\n", i);
141 			test(buf + 8 * (128 - i));
142 			if (i == 128)
143 				break;
144 			++i;
145 			if (i > 12)
146 				i += 3;
147 			if (i >= 128)
148 				i = 128;
149 		}
150 	}
151 
152 	try_tds_logout(login, tds, verbose);
153 	return 0;
154 }
155