Line data Source code
1 : #include "common.h"
2 :
3 : /* Test for SQLPutData */
4 :
5 : static const char test_text[] =
6 : "Nel mezzo del cammin di nostra vita\n" "mi ritrovai per una selva oscura\n" "che' la diritta via era smarrita.";
7 :
8 : #define BYTE_AT(n) (((n) * 245 + 123) & 0xff)
9 :
10 : static int
11 : to_sqlwchar(SQLWCHAR *dst, const char *src, int n)
12 : {
13 : int i;
14 3932 : for (i = 0; i < n; ++i)
15 3732 : dst[i] = src[i];
16 180 : return n * sizeof(SQLWCHAR);
17 : }
18 :
19 : static char sql[1024];
20 :
21 : static void
22 20 : Test(int direct)
23 : {
24 : SQLLEN ind;
25 20 : int len = strlen(test_text), n, i;
26 : const char *p;
27 : char *pp;
28 : SQLPOINTER ptr;
29 : unsigned char buf[256], *pb;
30 : SQLRETURN RetCode;
31 : int type, lc, sql_type;
32 :
33 : /* create table to hold data */
34 20 : odbc_command_with_result(odbc_stmt, "DROP TABLE #putdata");
35 20 : odbc_command("CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");
36 :
37 20 : sql_type = SQL_LONGVARCHAR;
38 20 : type = SQL_C_CHAR;
39 20 : lc = 1;
40 : for (;;) {
41 72 : CHKBindParameter(1, SQL_PARAM_INPUT, type, sql_type, 0, 0, (SQLPOINTER) 123, 0, &ind, "S");
42 : /* length required */
43 72 : ind = SQL_LEN_DATA_AT_EXEC(len * lc);
44 :
45 : /*
46 : * test for char
47 : */
48 :
49 72 : if (!direct) {
50 36 : CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");
51 :
52 36 : CHKExecute("Ne");
53 : } else {
54 36 : CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
55 : }
56 :
57 72 : p = test_text;
58 72 : n = 5;
59 72 : ptr = ((char*)0) + 0xdeadbeef;
60 72 : CHKParamData(&ptr, "Ne");
61 72 : if (ptr != (SQLPOINTER) 123) {
62 0 : fprintf(stderr, "%p\n", ptr);
63 0 : ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
64 : }
65 432 : while (*p) {
66 360 : int l = strlen(p);
67 :
68 360 : if (l < n)
69 72 : n = l;
70 360 : if (type == SQL_C_CHAR) {
71 180 : CHKPutData((char *) p, n, "S");
72 : } else {
73 : SQLWCHAR buf[256];
74 360 : CHKPutData((char *) buf, to_sqlwchar(buf, p, n), "S");
75 : }
76 360 : p += n;
77 360 : n *= 2;
78 : }
79 72 : CHKParamData(&ptr, "S");
80 :
81 72 : CHKParamData(&ptr, "E");
82 :
83 : /* check state and reset some possible buffers */
84 72 : odbc_command("DECLARE @i INT");
85 :
86 : /* use server ntext if available */
87 72 : if (sql_type == SQL_LONGVARCHAR && odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
88 32 : sql_type = SQL_WLONGVARCHAR;
89 32 : continue;
90 : }
91 :
92 40 : if (type != SQL_C_CHAR)
93 : break;
94 : sql_type = SQL_LONGVARCHAR;
95 : type = SQL_C_WCHAR;
96 : lc = sizeof(SQLWCHAR);
97 : }
98 :
99 : /* update row setting binary field */
100 5100 : for (i = 0; i < 255; ++i)
101 5100 : buf[i] = BYTE_AT(i);
102 :
103 : /*
104 : * test for binary
105 : */
106 :
107 20 : CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 4567, 0, &ind, "S");
108 20 : ind = SQL_LEN_DATA_AT_EXEC(254);
109 :
110 20 : CHKPrepare(T("UPDATE #putdata SET b = ?"), SQL_NTS, "S");
111 :
112 20 : CHKExecute("Ne");
113 :
114 20 : pb = buf;
115 20 : n = 7;
116 20 : CHKParamData(&ptr, "Ne");
117 20 : if (ptr != (SQLPOINTER) 4567)
118 0 : ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
119 140 : while (pb != (buf + 254)) {
120 120 : int l = buf + 254 - pb;
121 :
122 120 : if (l < n)
123 20 : n = l;
124 120 : CHKPutData((char *) pb, n, "S");
125 120 : pb += n;
126 120 : n *= 2;
127 : }
128 20 : CHKParamData(&ptr, "S");
129 :
130 20 : CHKParamData(&ptr, "E");
131 :
132 : /* check state and reset some possible buffers */
133 20 : odbc_command("DECLARE @i2 INT");
134 :
135 :
136 20 : CHKFreeStmt(SQL_RESET_PARAMS, "S");
137 :
138 : /* check inserts ... there should be all equal rows */
139 20 : strcpy(sql, "IF EXISTS(SELECT * FROM #putdata WHERE CONVERT(VARBINARY(255),b) <> 0x");
140 : /* append binary */
141 5100 : for (i = 0; i < 254; ++i)
142 5080 : sprintf(strchr(sql, 0), "%02x", buf[i]);
143 20 : strcat(sql, " OR CONVERT(VARCHAR(255),c) <> '");
144 : /* append string */
145 20 : pp = strchr(sql, 0);
146 20 : p = test_text;
147 : do {
148 2060 : *pp++ = *p;
149 2060 : if (*p == '\'')
150 20 : *pp++ = *p;
151 2060 : } while(*p++);
152 20 : strcat(sql, "') SELECT 1");
153 20 : odbc_check_no_row(sql);
154 :
155 20 : odbc_command("DELETE FROM #putdata");
156 :
157 : /* test len == 0 case from ML */
158 20 : type = SQL_C_CHAR;
159 : for (;;) {
160 60 : if (!direct)
161 20 : CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");
162 :
163 40 : CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind, "S");
164 :
165 40 : ind = SQL_LEN_DATA_AT_EXEC(0);
166 :
167 40 : if (!direct)
168 20 : CHKExecute("Ne");
169 : else
170 20 : CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
171 : RetCode = SQL_NEED_DATA;
172 120 : while (RetCode == SQL_NEED_DATA) {
173 80 : RetCode = SQLParamData(odbc_stmt, &ptr);
174 80 : if (RetCode == SQL_NEED_DATA) {
175 40 : if (type == SQL_C_CHAR) {
176 20 : CHKPutData("abc", 3, "S");
177 : } else {
178 : SQLWCHAR buf[10];
179 40 : CHKPutData(buf, to_sqlwchar(buf, "abc", 3), "S");
180 : }
181 : }
182 : }
183 40 : if (type != SQL_C_CHAR)
184 : break;
185 20 : type = SQL_C_WCHAR;
186 20 : odbc_reset_statement();
187 : }
188 :
189 : /* check inserts ... */
190 20 : odbc_check_no_row("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE 'abc') SELECT 1");
191 :
192 20 : odbc_command("DELETE FROM #putdata");
193 :
194 : /* test putting 0 bytes from Sebastien Flaesch */
195 20 : if (odbc_db_is_microsoft()) {
196 : type = SQL_C_CHAR;
197 : for (;;) {
198 48 : if (!direct)
199 16 : CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");
200 :
201 32 : CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 10, 0, (PTR) 2, 10, &ind, "S");
202 :
203 32 : ind = SQL_DATA_AT_EXEC;
204 :
205 32 : if (!direct)
206 16 : CHKExecute("Ne");
207 : else
208 16 : CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
209 : RetCode = SQL_NEED_DATA;
210 96 : while (RetCode == SQL_NEED_DATA) {
211 64 : RetCode = SQLParamData(odbc_stmt, &ptr);
212 64 : if (RetCode == SQL_NEED_DATA)
213 32 : CHKPutData("", 0, "S");
214 : }
215 32 : if (type != SQL_C_CHAR)
216 : break;
217 16 : type = SQL_C_WCHAR;
218 16 : odbc_reset_statement();
219 : }
220 :
221 : /* check inserts ... */
222 16 : odbc_check_no_row("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE '') SELECT 1");
223 : }
224 :
225 : /* TODO test cancel inside SQLExecute */
226 20 : }
227 :
228 : int
229 10 : main(void)
230 : {
231 10 : odbc_connect();
232 :
233 10 : Test(0);
234 10 : Test(1);
235 :
236 10 : odbc_disconnect();
237 :
238 10 : printf("Done.\n");
239 : return 0;
240 : }
|