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 560 : 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 560 : SQLLEN out_len = 0;
30 :
31 560 : SQLFreeStmt(odbc_stmt, SQL_UNBIND);
32 560 : SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS);
33 :
34 : /* execute a select to get data as wire */
35 560 : sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
36 560 : if (strncmp(value_to_convert, "0x", 2) == 0) {
37 22 : if (odbc_db_is_microsoft())
38 18 : 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 538 : } else if (strcmp(type, "SQL_VARIANT") == 0)
42 64 : sprintf(sbuf, "SELECT CONVERT(SQL_VARIANT, %s) AS data", value_to_convert);
43 474 : else if (strncmp(value_to_convert, "u&'", 3) == 0)
44 8 : sprintf(sbuf, "SELECT CONVERT(%s, %s) AS data", type, value_to_convert);
45 560 : if (ignore_select_error) {
46 560 : if (odbc_command2(sbuf, "SENo") == SQL_ERROR) {
47 18 : odbc_reset_statement();
48 18 : ignore_select_error = 0;
49 18 : ignore_result = 0;
50 18 : return;
51 : }
52 : } else {
53 0 : odbc_command(sbuf);
54 : }
55 542 : SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
56 542 : CHKFetch("S");
57 542 : CHKFetch("No");
58 542 : CHKMoreResults("No");
59 :
60 : /* test results */
61 542 : odbc_c2string(sbuf, out_c_type, out_buf, out_len);
62 :
63 542 : 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 542 : ignore_select_error = 0;
68 542 : ignore_result = 0;
69 : }
70 :
71 : static int
72 0 : get_int(const char *s)
73 : {
74 : char *end;
75 : long l;
76 :
77 0 : if (!s)
78 0 : odbc_fatal(": NULL int\n");
79 0 : l = strtol(s, &end, 0);
80 0 : if (end[0])
81 0 : odbc_fatal(": Invalid int\n");
82 0 : return (int) l;
83 : }
84 :
85 : static int
86 1088 : lookup(const char *name, const struct odbc_lookup_int *table)
87 : {
88 : int res;
89 :
90 1088 : if (!table)
91 0 : return get_int(name);
92 :
93 1088 : res = odbc_lookup(name, table, SQL_UNKNOWN_TYPE);
94 :
95 1088 : return res == SQL_UNKNOWN_TYPE ? get_int(name) : res;
96 : }
97 :
98 : int
99 8 : main(int argc, char *argv[])
100 : {
101 8 : int cond = 1;
102 :
103 : #define TEST_FILE "data.in"
104 8 : const char *in_file = FREETDS_SRCDIR "/" TEST_FILE;
105 : FILE *f;
106 :
107 8 : odbc_connect();
108 :
109 8 : odbc_init_bools();
110 :
111 8 : f = fopen(in_file, "r");
112 8 : if (!f)
113 0 : f = fopen(TEST_FILE, "r");
114 8 : if (!f) {
115 0 : fprintf(stderr, "error opening test file\n");
116 0 : exit(1);
117 : }
118 :
119 8 : odbc_init_parser(f);
120 1168 : for (;;) {
121 : char *p;
122 1176 : const char *cmd = odbc_get_cmd_line(&p, &cond);
123 :
124 1176 : if (!cmd)
125 : break;
126 :
127 : /* select type */
128 1168 : if (!strcmp(cmd, "select")) {
129 1056 : const char *type = odbc_get_str(&p);
130 1056 : const char *value = odbc_get_str(&p);
131 1056 : int c_type = lookup(odbc_get_tok(&p), odbc_sql_c_types);
132 1056 : const char *expected = odbc_get_str(&p);
133 :
134 2224 : if (!cond) continue;
135 :
136 536 : ignore_select_error = 1;
137 536 : Test(type, value, c_type, expected);
138 536 : continue;
139 : }
140 : /* select type setting condition */
141 112 : if (!strcmp(cmd, "select_cond")) {
142 32 : const char *bool_name = odbc_get_tok(&p);
143 32 : const char *type = odbc_get_tok(&p);
144 32 : const char *value = odbc_get_str(&p);
145 32 : int c_type = lookup(odbc_get_tok(&p), odbc_sql_c_types);
146 32 : const char *expected = odbc_get_str(&p);
147 32 : int save_result = result;
148 :
149 32 : if (!bool_name) odbc_fatal(": no condition name\n");
150 32 : if (!cond) continue;
151 :
152 24 : ignore_select_error = 1;
153 24 : ignore_result = 1;
154 24 : result = 0;
155 24 : Test(type, value, c_type, expected);
156 24 : odbc_set_bool(bool_name, result == 0);
157 24 : result = save_result;
158 24 : continue;
159 : }
160 : /* execute a sql command */
161 80 : if (!strcmp(cmd, "sql")) {
162 24 : const char *sql = odbc_get_str(&p);
163 :
164 24 : if (!cond) continue;
165 :
166 12 : odbc_command(sql);
167 12 : continue;
168 : }
169 56 : if (!strcmp(cmd, "sql_cond")) {
170 56 : const char *bool_name = odbc_get_tok(&p);
171 56 : const char *sql = odbc_get_str(&p);
172 :
173 56 : if (!cond) continue;
174 :
175 42 : odbc_set_bool(bool_name, odbc_command2(sql, "SENo") != SQL_ERROR);
176 42 : continue;
177 : }
178 0 : odbc_fatal(": unknown command\n");
179 : }
180 8 : odbc_clear_bools();
181 8 : fclose(f);
182 :
183 8 : printf("\n");
184 :
185 8 : odbc_disconnect();
186 :
187 8 : if (!result)
188 8 : printf("Done successfully!\n");
189 8 : return result;
190 : }
|