Line data Source code
1 : /*
2 : * Purpose: Test bcp in and out, and specifically bcp_colfmt()
3 : * Functions: bcp_colfmt bcp_columns bcp_exec bcp_init
4 : */
5 :
6 : #include "common.h"
7 :
8 : static int failed = 0;
9 :
10 : static void
11 0 : failure(const char *fmt, ...)
12 : {
13 : va_list ap;
14 :
15 0 : failed = 1;
16 :
17 0 : va_start(ap, fmt);
18 0 : vfprintf(stderr, fmt, ap);
19 0 : va_end(ap);
20 0 : }
21 :
22 : #define INFILE_NAME "t0016"
23 : #define TABLE_NAME "#dblib0016"
24 :
25 : static void test_file(const char *fn);
26 : static int compare_files(const char *fn1, const char *fn2);
27 : static unsigned count_file_rows(FILE *f);
28 : static DBPROCESS *dbproc;
29 :
30 : int
31 8 : main(int argc, char *argv[])
32 : {
33 : LOGINREC *login;
34 : char in_file[30];
35 : unsigned int n;
36 :
37 8 : setbuf(stdout, NULL);
38 8 : setbuf(stderr, NULL);
39 :
40 8 : set_malloc_options();
41 :
42 8 : read_login_info(argc, argv);
43 8 : printf("Starting %s\n", argv[0]);
44 8 : dbinit();
45 :
46 8 : dberrhandle(syb_err_handler);
47 8 : dbmsghandle(syb_msg_handler);
48 :
49 8 : printf("About to logon\n");
50 :
51 8 : login = dblogin();
52 8 : BCP_SETL(login, TRUE);
53 8 : DBSETLPWD(login, PASSWORD);
54 8 : DBSETLUSER(login, USER);
55 8 : DBSETLAPP(login, "t0016");
56 8 : DBSETLCHARSET(login, "UTF-8");
57 :
58 8 : dbproc = dbopen(login, SERVER);
59 8 : if (strlen(DATABASE)) {
60 8 : dbuse(dbproc, DATABASE);
61 : }
62 8 : dbloginfree(login);
63 8 : printf("After logon\n");
64 :
65 8 : strcpy(in_file, INFILE_NAME);
66 104 : for (n = 1; n <= 100; ++n) {
67 104 : test_file(in_file);
68 104 : sprintf(in_file, "%s_%d", INFILE_NAME, n);
69 104 : if (sql_reopen(in_file) != SUCCEED)
70 : break;
71 : }
72 :
73 8 : dbclose(dbproc);
74 8 : dbexit();
75 :
76 8 : printf("dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
77 8 : return failed ? 1 : 0;
78 : }
79 :
80 : static int got_error = 0;
81 :
82 : static int
83 12 : ignore_msg_handler(DBPROCESS * dbproc, DBINT msgno, int state, int severity, char *text, char *server, char *proc, int line)
84 : {
85 12 : got_error = 1;
86 12 : return 0;
87 : }
88 :
89 : static int
90 12 : ignore_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
91 : {
92 12 : got_error = 1;
93 12 : return INT_CANCEL;
94 : }
95 :
96 : static char line1[1024*16];
97 : static char line2[1024*16];
98 :
99 : static void
100 104 : test_file(const char *fn)
101 : {
102 : int i;
103 : RETCODE ret;
104 104 : int num_cols = 0;
105 104 : const char *out_file = "t0016.out";
106 104 : const char *err_file = "t0016.err";
107 : DBINT rows_copied;
108 104 : unsigned num_rows = 2;
109 :
110 : FILE *input_file;
111 :
112 : char in_file[256];
113 104 : snprintf(in_file, sizeof(in_file), "%s/%s.in", FREETDS_SRCDIR, fn);
114 :
115 104 : input_file = fopen(in_file, "rb");
116 104 : if (!input_file) {
117 0 : sprintf(in_file, "%s.in", fn);
118 0 : input_file = fopen(in_file, "rb");
119 : }
120 104 : if (!input_file) {
121 0 : fprintf(stderr, "could not open %s\n", in_file);
122 0 : exit(1);
123 : }
124 104 : num_rows = count_file_rows(input_file);
125 104 : fclose(input_file);
126 :
127 104 : dberrhandle(ignore_err_handler);
128 104 : dbmsghandle(ignore_msg_handler);
129 :
130 104 : printf("Creating table '%s'\n", TABLE_NAME);
131 104 : got_error = 0;
132 104 : sql_cmd(dbproc);
133 104 : dbsqlexec(dbproc);
134 308 : while (dbresults(dbproc) != NO_MORE_RESULTS)
135 100 : continue;
136 :
137 104 : dberrhandle(syb_err_handler);
138 104 : dbmsghandle(syb_msg_handler);
139 :
140 104 : if (got_error)
141 12 : return;
142 :
143 : /* BCP in */
144 :
145 92 : printf("bcp_init with in_file as '%s'\n", in_file);
146 92 : ret = bcp_init(dbproc, TABLE_NAME, in_file, err_file, DB_IN);
147 92 : if (ret != SUCCEED)
148 0 : failure("bcp_init failed\n");
149 :
150 92 : printf("return from bcp_init = %d\n", ret);
151 :
152 92 : ret = sql_cmd(dbproc);
153 92 : printf("return from dbcmd = %d\n", ret);
154 :
155 92 : ret = dbsqlexec(dbproc);
156 92 : printf("return from dbsqlexec = %d\n", ret);
157 :
158 92 : if (dbresults(dbproc) != FAIL) {
159 92 : num_cols = dbnumcols(dbproc);
160 92 : printf("Number of columns = %d\n", num_cols);
161 :
162 92 : while (dbnextrow(dbproc) != NO_MORE_ROWS) {
163 : }
164 : }
165 :
166 92 : ret = bcp_columns(dbproc, num_cols);
167 92 : if (ret != SUCCEED)
168 0 : failure("bcp_columns failed\n");
169 92 : printf("return from bcp_columns = %d\n", ret);
170 :
171 554 : for (i = 1; i < num_cols; i++) {
172 462 : if ((ret = bcp_colfmt(dbproc, i, SYBCHAR, 0, -1, (const BYTE *) "\t", sizeof(char), i)) == FAIL)
173 0 : failure("return from bcp_colfmt = %d\n", ret);
174 : }
175 :
176 92 : if ((ret = bcp_colfmt(dbproc, num_cols, SYBCHAR, 0, -1, (const BYTE *) "\n", sizeof(char), num_cols)) == FAIL)
177 0 : failure("return from bcp_colfmt = %d\n", ret);
178 :
179 :
180 92 : ret = bcp_exec(dbproc, &rows_copied);
181 92 : if (ret != SUCCEED || rows_copied != num_rows)
182 0 : failure("bcp_exec failed\n");
183 :
184 92 : printf("%d rows copied in\n", rows_copied);
185 :
186 : /* BCP out */
187 :
188 92 : rows_copied = 0;
189 92 : ret = bcp_init(dbproc, TABLE_NAME, out_file, err_file, DB_OUT);
190 92 : if (ret != SUCCEED)
191 0 : failure("bcp_int failed\n");
192 :
193 92 : printf("select\n");
194 92 : sql_cmd(dbproc);
195 92 : dbsqlexec(dbproc);
196 :
197 92 : if (dbresults(dbproc) != FAIL) {
198 92 : num_cols = dbnumcols(dbproc);
199 92 : while (dbnextrow(dbproc) != NO_MORE_ROWS) {
200 : }
201 : }
202 :
203 92 : ret = bcp_columns(dbproc, num_cols);
204 :
205 554 : for (i = 1; i < num_cols; i++) {
206 462 : if ((ret = bcp_colfmt(dbproc, i, SYBCHAR, 0, -1, (const BYTE *) "\t", sizeof(char), i)) == FAIL)
207 0 : failure("return from bcp_colfmt = %d\n", ret);
208 : }
209 :
210 92 : if ((ret = bcp_colfmt(dbproc, num_cols, SYBCHAR, 0, -1, (const BYTE *) "\n", sizeof(char), num_cols)) == FAIL)
211 0 : failure("return from bcp_colfmt = %d\n", ret);
212 :
213 92 : ret = bcp_exec(dbproc, &rows_copied);
214 92 : if (ret != SUCCEED || rows_copied != num_rows)
215 0 : failure("bcp_exec failed\n");
216 :
217 92 : printf("%d rows copied out\n", rows_copied);
218 :
219 92 : printf("Dropping table '%s'\n", TABLE_NAME);
220 92 : sql_cmd(dbproc);
221 92 : dbsqlexec(dbproc);
222 276 : while (dbresults(dbproc) != NO_MORE_RESULTS)
223 92 : continue;
224 :
225 92 : if (failed)
226 : return;
227 :
228 92 : if (compare_files(in_file, out_file))
229 92 : printf("Input and output files are equal\n");
230 : else
231 0 : failed = 1;
232 : }
233 :
234 864 : static size_t fgets_raw(char *s, int len, FILE *f)
235 : {
236 864 : char *p = s;
237 :
238 578620 : while (len > 1) {
239 577756 : int c = getc(f);
240 577756 : if (c == EOF) {
241 288 : if (ferror(f))
242 : return 0;
243 : break;
244 : }
245 577468 : *p++ = c;
246 577468 : --len;
247 577468 : if (c == '\n')
248 : break;
249 : }
250 864 : if (len > 0)
251 864 : *p = 0;
252 864 : return p - s;
253 : }
254 :
255 92 : static int compare_files(const char *fn1, const char *fn2)
256 : {
257 92 : int equal = 1;
258 : FILE *f1, *f2;
259 : size_t s1, s2;
260 :
261 : /* check input and output should be the same */
262 92 : f1 = fopen(fn1, "r");
263 92 : f2 = fopen(fn2, "r");
264 92 : if (f1 != NULL && f2 != NULL) {
265 : int line = 1;
266 :
267 184 : for (;; ++line) {
268 460 : s1 = fgets_raw(line1, sizeof(line1), f1);
269 276 : s2 = fgets_raw(line2, sizeof(line2), f2);
270 :
271 : /* EOF or error of one */
272 276 : if (!!s1 != !!s2) {
273 0 : equal = 0;
274 0 : failure("error reading a file or EOF of a file\n");
275 0 : break;
276 : }
277 :
278 : /* EOF or error of both */
279 276 : if (!s1) {
280 92 : if (feof(f1) && feof(f2))
281 : break;
282 0 : equal = 0;
283 0 : failure("error reading a file\n");
284 0 : break;
285 : }
286 :
287 184 : if (s1 != s2 || memcmp(line1, line2, s1) != 0) {
288 0 : equal = 0;
289 0 : failure("File different at line %d\n"
290 : " input: %s"
291 : " output: %s",
292 : line, line1, line2);
293 : }
294 : }
295 : } else {
296 0 : equal = 0;
297 0 : failure("error opening files\n");
298 : }
299 92 : if (f1)
300 92 : fclose(f1);
301 92 : if (f2)
302 92 : fclose(f2);
303 :
304 92 : return equal;
305 : }
306 :
307 104 : static unsigned count_file_rows(FILE *f)
308 : {
309 : size_t s;
310 104 : unsigned rows = 1;
311 104 : char last = '\n';
312 :
313 104 : assert(f);
314 :
315 312 : while ((s = fgets_raw(line1, sizeof(line1), f)) != 0) {
316 208 : last = line1[s-1];
317 208 : if (last == '\n')
318 208 : ++rows;
319 : }
320 104 : if (last == '\n')
321 104 : --rows;
322 104 : assert(!ferror(f));
323 104 : return rows;
324 : }
|