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