Line data Source code
1 : /*
2 : * Purpose: Test sending and receiving TEXT datatype
3 : * Functions: dbbind dbmoretext dbreadtext dbtxptr dbtxtimestamp dbwritetext
4 : */
5 :
6 : #include "common.h"
7 :
8 : #include <freetds/bool.h>
9 :
10 : #define BLOB_BLOCK_SIZE 4096
11 :
12 : static char *testargs[] = { "", FREETDS_SRCDIR "/data.bin", "t0014.out" };
13 :
14 : static int
15 16 : test(int argc, char **argv, bool over4k)
16 : {
17 16 : const int rows_to_add = 3;
18 : LOGINREC *login;
19 : DBPROCESS *dbproc;
20 : DBPROCESS *blobproc;
21 : int i;
22 : DBINT testint;
23 : FILE *fp;
24 : ptrdiff_t result;
25 : long isiz;
26 : char *blob, *rblob;
27 : unsigned char *textPtr, *timeStamp;
28 : char objname[256];
29 : char sqlCmd[256];
30 : char rbuf[BLOB_BLOCK_SIZE];
31 : size_t numread;
32 : int numtowrite, numwritten;
33 :
34 16 : set_malloc_options();
35 :
36 16 : read_login_info(argc, argv);
37 16 : printf("Starting %s\n", argv[0]);
38 16 : dbinit();
39 :
40 16 : dberrhandle(syb_err_handler);
41 16 : dbmsghandle(syb_msg_handler);
42 :
43 16 : printf("About to logon\n");
44 :
45 16 : login = dblogin();
46 16 : DBSETLPWD(login, PASSWORD);
47 16 : DBSETLUSER(login, USER);
48 16 : DBSETLAPP(login, "t0014");
49 :
50 16 : printf("About to open %s..%s for user '%s'\n", SERVER, DATABASE, USER);
51 :
52 16 : dbproc = dbopen(login, SERVER);
53 16 : blobproc = dbopen(login, SERVER);
54 16 : if (strlen(DATABASE)) {
55 16 : dbuse(dbproc, DATABASE);
56 16 : dbuse(blobproc, DATABASE);
57 : }
58 16 : dbloginfree(login);
59 16 : printf("After logon\n");
60 :
61 16 : printf("About to read binary input file\n");
62 :
63 16 : if (argc == 1) {
64 : argv = testargs;
65 : argc = 3;
66 : }
67 0 : if (argc < 3) {
68 0 : fprintf(stderr, "Usage: %s infile outfile\n", argv[0]);
69 0 : return 1;
70 : }
71 :
72 16 : if ((fp = fopen(argv[1], "rb")) == NULL) {
73 0 : fprintf(stderr, "Cannot open input file: %s\n", argv[1]);
74 0 : return 2;
75 : }
76 16 : result = fseek(fp, 0, SEEK_END);
77 16 : isiz = ftell(fp);
78 16 : result = fseek(fp, 0, SEEK_SET);
79 :
80 16 : blob = (char *) malloc(isiz);
81 16 : assert(blob);
82 16 : result = fread((void *) blob, isiz, 1, fp);
83 16 : assert(result == 1);
84 16 : fclose(fp);
85 :
86 : /* FIXME this test seem to not work using temporary tables (sybase?)... */
87 16 : printf("Dropping table\n");
88 16 : sql_cmd(dbproc);
89 16 : dbsqlexec(dbproc);
90 16 : while (dbresults(dbproc) != NO_MORE_RESULTS) {
91 : /* nop */
92 : }
93 :
94 16 : printf("creating table\n");
95 16 : sql_cmd(dbproc);
96 16 : dbsqlexec(dbproc);
97 16 : while (dbresults(dbproc) != NO_MORE_RESULTS) {
98 : /* nop */
99 : }
100 :
101 :
102 16 : printf("insert\n");
103 64 : for (i = 0; i < rows_to_add; i++) {
104 48 : sql_cmd(dbproc);
105 48 : dbsqlexec(dbproc);
106 48 : while (dbresults(dbproc) != NO_MORE_RESULTS) {
107 : /* nop */
108 : }
109 : }
110 :
111 36 : for (i = 0; i < rows_to_add; i++) {
112 40 : sql_cmd(dbproc);
113 40 : dbsqlexec(dbproc);
114 40 : if (dbresults(dbproc) != SUCCEED) {
115 0 : fprintf(stderr, "Error inserting blob\n");
116 0 : return 4;
117 : }
118 :
119 76 : while ((result = dbnextrow(dbproc)) != NO_MORE_ROWS) {
120 40 : result = REG_ROW;
121 40 : result = DBTXPLEN;
122 40 : strcpy(objname, "dblib0014.PigTure");
123 40 : textPtr = dbtxptr(dbproc, 1);
124 40 : timeStamp = dbtxtimestamp(dbproc, 1);
125 :
126 : #ifdef DBTDS_7_2
127 40 : if (!textPtr && !timeStamp && dbtds(dbproc) >= DBTDS_7_2) {
128 4 : printf("Protocol 7.2+ detected, test not supported\n");
129 4 : free(blob);
130 4 : dbexit();
131 4 : exit(0);
132 : }
133 : #endif
134 :
135 : /* leave NULL on first row */
136 36 : if (i == 0)
137 12 : continue;
138 :
139 : /*
140 : * Use #ifdef if you want to test dbmoretext mode (needed for 16-bit apps)
141 : * Use #ifndef for big buffer version (32-bit)
142 : */
143 24 : if (over4k) {
144 12 : if (dbwritetext(blobproc, objname, textPtr, DBTXPLEN, timeStamp, TRUE, isiz, (BYTE*) blob) != SUCCEED)
145 : return 5;
146 : } else {
147 12 : if (dbwritetext(blobproc, objname, textPtr, DBTXPLEN, timeStamp, TRUE, isiz, NULL) != SUCCEED)
148 : return 15;
149 12 : dbsqlok(blobproc);
150 12 : dbresults(blobproc);
151 :
152 12 : numtowrite = 0;
153 : /* Send the update value in chunks. */
154 192 : for (numwritten = 0; numwritten < isiz; numwritten += numtowrite) {
155 180 : numtowrite = (isiz - numwritten);
156 180 : if (numtowrite > BLOB_BLOCK_SIZE)
157 168 : numtowrite = BLOB_BLOCK_SIZE;
158 180 : dbmoretext(blobproc, (DBINT) numtowrite, (BYTE *) (blob + numwritten));
159 : }
160 12 : dbsqlok(blobproc);
161 36 : while (dbresults(blobproc) != NO_MORE_RESULTS)
162 12 : continue;
163 : }
164 : }
165 : }
166 :
167 12 : printf("select\n");
168 :
169 12 : sql_cmd(dbproc);
170 12 : dbsqlexec(dbproc);
171 :
172 12 : if (dbresults(dbproc) != SUCCEED) {
173 0 : printf("Was expecting a result set.");
174 0 : exit(1);
175 : }
176 :
177 24 : for (i = 1; i <= dbnumcols(dbproc); i++) {
178 24 : printf("col %d is %s\n", i, dbcolname(dbproc, i));
179 : }
180 :
181 12 : if (SUCCEED != dbbind(dbproc, 1, INTBIND, -1, (BYTE *) & testint)) {
182 0 : fprintf(stderr, "Had problem with bind\n");
183 0 : abort();
184 : }
185 :
186 84 : for (i = 0; i < rows_to_add; i++) {
187 : char expected[1024];
188 :
189 36 : sprintf(expected, "row %03d", i);
190 :
191 36 : if (REG_ROW != dbnextrow(dbproc)) {
192 0 : fprintf(stderr, "Failed. Expected a row\n");
193 0 : exit(1);
194 : }
195 36 : if (testint != i) {
196 0 : fprintf(stderr, "Failed. Expected i to be %d, was %d\n", i, (int) testint);
197 0 : abort();
198 : }
199 :
200 : /* get the image */
201 36 : strcpy(sqlCmd, "SET TEXTSIZE 2147483647");
202 36 : dbcmd(blobproc, sqlCmd);
203 36 : dbsqlexec(blobproc);
204 :
205 36 : if (dbresults(blobproc) != SUCCEED) {
206 0 : dbcancel(blobproc);
207 0 : return 16;
208 : }
209 :
210 36 : sprintf(sqlCmd, "SELECT PigTure FROM dblib0014 WHERE i = %d", i);
211 36 : dbcmd(blobproc, sqlCmd);
212 36 : dbsqlexec(blobproc);
213 36 : if (dbresults(blobproc) != SUCCEED) {
214 0 : fprintf(stderr, "Error extracting blob\n");
215 0 : return 6;
216 : }
217 :
218 : numread = 0;
219 : rblob = NULL;
220 432 : while ((result = dbreadtext(blobproc, rbuf, BLOB_BLOCK_SIZE)) != NO_MORE_ROWS) {
221 396 : assert(result >= 0);
222 396 : if (result != 0) { /* this indicates not end of row */
223 360 : rblob = (char*) realloc(rblob, result + numread);
224 360 : assert(rblob);
225 360 : memcpy((void *) (rblob + numread), (void *) rbuf, result);
226 360 : numread += result;
227 : }
228 : }
229 :
230 : /* first row is NULL */
231 36 : if (rblob != NULL && i == 0) {
232 0 : fputs("Blob data received\n", stderr);
233 0 : return 7;
234 : }
235 36 : if (rblob == NULL && i > 0) {
236 0 : fputs("No blob data received\n", stderr);
237 0 : return 7;
238 : }
239 :
240 36 : if (i == 1) {
241 12 : printf("Saving send blob data row to file: %s\n", argv[2]);
242 12 : if ((fp = fopen(argv[2], "wb")) == NULL) {
243 0 : free(blob);
244 0 : free(rblob);
245 0 : fprintf(stderr, "Unable to open output file: %s\n", argv[2]);
246 0 : return 3;
247 : }
248 :
249 12 : result = (long) fwrite((void *) rblob, numread, 1, fp);
250 12 : fclose(fp);
251 : }
252 :
253 36 : printf("Read blob data row %d --> %s %lu byte comparison\n",
254 36 : (int) testint, (memcmp(blob, rblob, numread)) ? "failed" : "PASSED", (long unsigned int) numread);
255 36 : free(rblob);
256 : }
257 :
258 12 : if (dbnextrow(dbproc) != NO_MORE_ROWS) {
259 0 : fprintf(stderr, "Was expecting no more rows\n");
260 0 : exit(1);
261 : }
262 :
263 12 : free(blob);
264 :
265 12 : printf("Dropping table\n");
266 12 : sql_cmd(dbproc);
267 12 : dbsqlexec(dbproc);
268 12 : while (dbresults(dbproc) != NO_MORE_RESULTS) {
269 : /* nop */
270 : }
271 :
272 12 : dbexit();
273 :
274 12 : return 0;
275 : }
276 :
277 10 : TEST_MAIN()
278 : {
279 10 : int res = test(argc, argv, false);
280 6 : if (!res)
281 6 : res = test(argc, argv, true);
282 6 : if (res)
283 : return res;
284 :
285 6 : printf("dblib okay on %s\n", __FILE__);
286 6 : return 0;
287 : }
288 :
|