Line data Source code
1 : /*
2 : * Test reading data with SQLBindCol
3 : */
4 : #include "common.h"
5 : #include <assert.h>
6 : #include <ctype.h>
7 : #include "parser.h"
8 :
9 : /*
10 : * This test is useful to test odbc_tds2sql function
11 : * odbc_tds2sql have some particular cases:
12 : * (1) numeric -> binary numeric is different in ODBC
13 : * (2) * -> binary dependent from libTDS representation and ODBC one
14 : * (3) binary -> char TODO
15 : * (4) date -> char different format
16 : * Also we have to check normal char and wide char
17 : */
18 :
19 : static int result = 0;
20 :
21 : static int ignore_select_error = 0;
22 : static int ignore_result = 0;
23 :
24 : static void
25 730 : Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, const char *expected)
26 : {
27 : char sbuf[1024];
28 : unsigned char out_buf[256];
29 730 : SQLLEN out_len = 0;
30 :
31 730 : SQLFreeStmt(odbc_stmt, SQL_UNBIND);
32 730 : SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS);
33 :
34 : /* execute a select to get data as wire */
35 730 : sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
36 730 : if (strncmp(value_to_convert, "0x", 2) == 0) {
37 28 : if (odbc_db_is_microsoft())
38 24 : sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert);
39 : else
40 4 : sprintf(sbuf, "SELECT CONVERT(%s, %s)", type, value_to_convert);
41 702 : } else if (strcmp(type, "SQL_VARIANT") == 0)
42 92 : sprintf(sbuf, "SELECT CONVERT(SQL_VARIANT, %s) AS data", value_to_convert);
43 610 : else if (strncmp(value_to_convert, "u&'", 3) == 0)
44 10 : sprintf(sbuf, "SELECT CONVERT(%s, %s) AS data", type, value_to_convert);
45 730 : if (ignore_select_error) {
46 730 : if (odbc_command2(sbuf, "SENo") == SQL_ERROR) {
47 20 : odbc_reset_statement();
48 20 : ignore_select_error = 0;
49 20 : ignore_result = 0;
50 20 : return;
51 : }
52 : } else {
53 0 : odbc_command(sbuf);
54 : }
55 710 : SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
56 710 : CHKFetch("S");
57 710 : CHKFetch("No");
58 710 : CHKMoreResults("No");
59 :
60 : /* test results */
61 710 : odbc_c2string(sbuf, out_c_type, out_buf, out_len);
62 :
63 710 : if (!ignore_result && strcmp(sbuf, expected) != 0) {
64 0 : fprintf(stderr, "Wrong result\n Got: %s\n Expected: %s\n", sbuf, expected);
65 0 : result = 1;
66 : }
67 710 : ignore_select_error = 0;
68 710 : ignore_result = 0;
69 : }
70 :
71 : static int
72 0 : get_int(const char *s, odbc_parser *parser)
73 : {
74 : char *end;
75 : long l;
76 :
77 0 : if (!s)
78 0 : odbc_fatal(parser, ": NULL int\n");
79 0 : l = strtol(s, &end, 0);
80 0 : if (end[0])
81 0 : odbc_fatal(parser, ": Invalid int\n");
82 0 : return (int) l;
83 : }
84 :
85 : static int
86 1360 : lookup(const char *name, const struct odbc_lookup_int *table, odbc_parser *parser)
87 : {
88 : int res;
89 :
90 1360 : if (!table)
91 0 : return get_int(name, parser);
92 :
93 1360 : res = odbc_lookup(name, table, SQL_UNKNOWN_TYPE);
94 :
95 1360 : return res == SQL_UNKNOWN_TYPE ? get_int(name, parser) : res;
96 : }
97 :
98 10 : TEST_MAIN()
99 : {
100 10 : bool cond = true;
101 :
102 : #define TEST_FILE "data.in"
103 10 : const char *in_file = FREETDS_SRCDIR "/" TEST_FILE;
104 : FILE *f;
105 : odbc_parser *parser;
106 :
107 10 : odbc_connect();
108 :
109 10 : f = fopen(in_file, "r");
110 10 : if (!f)
111 0 : f = fopen(TEST_FILE, "r");
112 10 : if (!f) {
113 0 : fprintf(stderr, "error opening test file\n");
114 0 : exit(1);
115 : }
116 :
117 : /* cache version */
118 10 : odbc_tds_version();
119 :
120 10 : parser = odbc_init_parser(f);
121 1460 : for (;;) {
122 : char *p;
123 1470 : const char *cmd = odbc_get_cmd_line(parser, &p, &cond);
124 :
125 1470 : if (!cmd)
126 : break;
127 :
128 : /* select type */
129 1460 : if (!strcmp(cmd, "select")) {
130 1320 : const char *type = odbc_get_str(parser, &p);
131 1320 : const char *value = odbc_get_str(parser, &p);
132 1320 : int c_type = lookup(odbc_get_tok(&p), odbc_sql_c_types, parser);
133 1320 : const char *expected = odbc_get_str(parser, &p);
134 :
135 2780 : if (!cond) continue;
136 :
137 698 : ignore_select_error = 1;
138 698 : Test(type, value, c_type, expected);
139 698 : continue;
140 : }
141 : /* select type setting condition */
142 140 : if (!strcmp(cmd, "select_cond")) {
143 40 : const char *bool_name = odbc_get_tok(&p);
144 40 : const char *type = odbc_get_tok(&p);
145 40 : const char *value = odbc_get_str(parser, &p);
146 40 : int c_type = lookup(odbc_get_tok(&p), odbc_sql_c_types, parser);
147 40 : const char *expected = odbc_get_str(parser, &p);
148 40 : int save_result = result;
149 :
150 40 : if (!bool_name) odbc_fatal(parser, ": no condition name\n");
151 40 : if (!cond) continue;
152 :
153 32 : ignore_select_error = 1;
154 32 : ignore_result = 1;
155 32 : result = 0;
156 32 : Test(type, value, c_type, expected);
157 32 : odbc_set_bool(parser, bool_name, result == 0);
158 32 : result = save_result;
159 32 : continue;
160 : }
161 : /* execute a sql command */
162 100 : if (!strcmp(cmd, "sql")) {
163 30 : const char *sql = odbc_get_str(parser, &p);
164 :
165 30 : if (!cond) continue;
166 :
167 18 : odbc_command(sql);
168 18 : continue;
169 : }
170 70 : if (!strcmp(cmd, "sql_cond")) {
171 70 : const char *bool_name = odbc_get_tok(&p);
172 70 : const char *sql = odbc_get_str(parser, &p);
173 :
174 70 : if (!cond) continue;
175 :
176 54 : odbc_set_bool(parser, bool_name, odbc_command2(sql, "SENo") != SQL_ERROR);
177 54 : continue;
178 : }
179 0 : odbc_fatal(parser, ": unknown command\n");
180 : }
181 10 : odbc_free_parser(parser);
182 10 : fclose(f);
183 :
184 10 : printf("\n");
185 :
186 10 : odbc_disconnect();
187 :
188 10 : if (!result)
189 10 : printf("Done successfully!\n");
190 10 : return result;
191 : }
|