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