Line data Source code
1 : #include "common.h"
2 :
3 : /*
4 : * This test try do discovery how dblib process token looking for state
5 : * at every iteration. It issue a query to server and check
6 : * - row count (valid number means DONE processed)
7 : * - if possible to send another query (means state IDLE)
8 : * - if error readed (means ERROR token readed)
9 : * - if status present (PARAMRESULT token readed)
10 : * - if parameter present (PARAM token readed)
11 : * It try these query types:
12 : * - normal row
13 : * - normal row with no count
14 : * - normal row without rows
15 : * - error query
16 : * - store procedure call with output parameters
17 : */
18 :
19 : /* Forward declarations of the error handler and message handler. */
20 : static int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
21 : static int msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname,
22 : int line);
23 :
24 : static DBPROCESS *dbproc;
25 : static int silent = 0;
26 : static int check_idle = 0;
27 :
28 : /* print functions adapted from src/dblib/dblib.c */
29 : static const char *
30 254 : prdbretcode(int retcode)
31 : {
32 : static char unknown[24];
33 254 : switch(retcode) {
34 : case REG_ROW: return "REG_ROW/MORE_ROWS";
35 214 : case NO_MORE_ROWS: return "NO_MORE_ROWS";
36 0 : case BUF_FULL: return "BUF_FULL";
37 0 : case NO_MORE_RESULTS: return "NO_MORE_RESULTS";
38 0 : case SUCCEED: return "SUCCEED";
39 0 : case FAIL: return "FAIL";
40 0 : default:
41 0 : sprintf(unknown, "oops: %u ??", retcode);
42 : }
43 0 : return unknown;
44 : }
45 :
46 : static const char *
47 252 : prretcode(int retcode)
48 : {
49 : static char unknown[24];
50 252 : switch(retcode) {
51 : case SUCCEED: return "SUCCEED";
52 10 : case FAIL: return "FAIL";
53 138 : case NO_MORE_RESULTS: return "NO_MORE_RESULTS";
54 0 : default:
55 0 : sprintf(unknown, "oops: %u ??", retcode);
56 : }
57 0 : return unknown;
58 : }
59 :
60 : static void
61 100 : query(const char comment[])
62 : {
63 100 : if (comment)
64 40 : printf("%s\n", comment);
65 100 : sql_cmd(dbproc);
66 100 : dbsqlexec(dbproc);
67 100 : while (dbresults(dbproc) == SUCCEED) {
68 : /* nop */
69 : }
70 100 : }
71 :
72 : typedef const char* (*prfunc)(int);
73 :
74 : static void
75 506 : check_state(const char name[], prfunc print, int erc)
76 : {
77 506 : printf("State %-15s %-20s ", name, print(erc));
78 506 : if (dbnumcols(dbproc) > 0)
79 376 : printf("COLS(%d) ", dbnumcols(dbproc));
80 : /* row count */
81 506 : if (dbcount(dbproc) >= 0)
82 88 : printf("ROWS(%d) ", (int) dbcount(dbproc));
83 506 : silent = 1;
84 506 : if (dbdata(dbproc, 1))
85 130 : printf("DATA ");
86 506 : silent = 0;
87 : /* if status present */
88 506 : if (dbretstatus(dbproc) == TRUE)
89 0 : printf("STATUS %d ", (int) dbretstatus(dbproc));
90 : /* if parameter present */
91 506 : if (dbnumrets(dbproc) > 0)
92 8 : printf("PARAMS ");
93 : /*
94 : * if possible to send another query
95 : * NOTE this must be the last
96 : */
97 506 : if (check_idle) {
98 60 : silent = 1;
99 60 : dbcmd(dbproc, "declare @i int ");
100 60 : if (FAIL != dbsqlexec(dbproc))
101 20 : printf("IDLE ");
102 60 : silent = 0;
103 : }
104 506 : printf("\n");
105 506 : }
106 :
107 : static void
108 60 : do_test(const char comment[])
109 : {
110 : int ret;
111 60 : prfunc print_with = NULL;
112 :
113 60 : if (comment)
114 60 : printf("%s\n", comment);
115 60 : sql_cmd(dbproc);
116 :
117 60 : check_state("sqlexec ", prretcode, dbsqlexec(dbproc));
118 :
119 60 : check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
120 60 : check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
121 60 : check_state("results ", prretcode, dbresults(dbproc));
122 60 : check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
123 60 : check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
124 :
125 60 : check_idle = 0;
126 : for (;;) {
127 72 : ret = dbresults(dbproc);
128 72 : check_state("results ", prretcode, ret);
129 72 : if (ret != SUCCEED) {
130 60 : print_with = prretcode;
131 : break;
132 : }
133 :
134 : do {
135 14 : ret = dbnextrow(dbproc);
136 14 : check_state("nextrow ", prdbretcode, ret);
137 14 : } while (ret == REG_ROW);
138 : print_with = prdbretcode;
139 : }
140 60 : check_state("more results?", print_with, ret);
141 60 : }
142 :
143 10 : TEST_MAIN()
144 : {
145 : static const int invalid_column_name = 207;
146 : LOGINREC *login; /* Our login information. */
147 : int i;
148 :
149 10 : setbuf(stdout, NULL);
150 10 : read_login_info(argc, argv);
151 :
152 10 : if (dbinit() == FAIL)
153 0 : exit(1);
154 :
155 10 : dberrhandle(err_handler);
156 10 : dbmsghandle(msg_handler);
157 :
158 : #if 0
159 : /*
160 : * FIXME: Should be able to use the common err/msg handlers, but something about
161 : * the IDLE checking causes them to fail. Not sure about purpose of IDLE checking.
162 : * -- jkl January 2009
163 : */
164 : dberrhandle(syb_err_handler);
165 : dbmsghandle(syb_msg_handler);
166 : #endif
167 :
168 10 : login = dblogin();
169 10 : DBSETLUSER(login, USER);
170 10 : DBSETLPWD(login, PASSWORD);
171 10 : DBSETLAPP(login, "done_handling");
172 :
173 10 : dbproc = dbopen(login, SERVER);
174 10 : dbloginfree(login);
175 10 : if (!dbproc)
176 0 : exit(1);
177 10 : if (strlen(DATABASE))
178 10 : dbuse(dbproc, DATABASE);
179 :
180 60 : for (i=0; i < 6; i++)
181 60 : query(NULL);
182 : #if 0
183 : check_state("setup done ", prretcode, erc);
184 :
185 : printf("wasting results\n");
186 : while ((erc = dbresults(dbproc)) == SUCCEED) {
187 : while (dbnextrow(dbproc) == REG_ROW); /* no-op */
188 : }
189 : #endif
190 10 : check_idle = 1;
191 :
192 10 : do_test("normal row with rowcount on");
193 10 : query("turn rowcount off");
194 10 : do_test("normal row with rowcount off");
195 10 : query("turn rowcount back on");
196 10 : do_test("normal row without rows");
197 10 : dbsetuserdata(dbproc, (BYTE*) &invalid_column_name);
198 10 : do_test("error query");
199 10 : do_test("stored procedure call with output parameters");
200 :
201 10 : do_test("execute done2");
202 :
203 10 : query("drop done_test");
204 :
205 10 : query("drop done_test2");
206 :
207 10 : dbexit();
208 10 : return 0;
209 : }
210 :
211 : static int
212 50 : err_handler(DBPROCESS * dbproc TDS_UNUSED, int severity, int dberr TDS_UNUSED, int oserr, char *dberrstr, char *oserrstr)
213 : {
214 50 : if (silent)
215 : return INT_CANCEL;
216 :
217 10 : fflush(stdout);
218 10 : fprintf(stderr, "DB-Library error (severity %d):\n\t%s\n", severity, dberrstr);
219 :
220 10 : if (oserr != DBNOERR)
221 0 : fprintf(stderr, "Operating-system error:\n\t%s\n", oserrstr ? oserrstr : "(null)");
222 10 : fflush(stderr);
223 :
224 10 : return INT_CANCEL;
225 : }
226 :
227 : static int
228 38 : msg_handler(DBPROCESS * dbproc TDS_UNUSED, DBINT msgno, int msgstate, int severity,
229 : char *msgtext, char *srvname, char *procname, int line)
230 : {
231 38 : if (silent)
232 : return 0;
233 :
234 38 : fflush(stdout);
235 38 : fprintf(stderr, "Msg %d, Level %d, State %d\n", (int) msgno, severity, msgstate);
236 :
237 38 : if (strlen(srvname) > 0)
238 38 : fprintf(stderr, "Server '%s', ", srvname);
239 38 : if (procname && strlen(procname) > 0) {
240 0 : fprintf(stderr, "Procedure '%s', ", procname);
241 0 : if (line > 0)
242 0 : fprintf(stderr, "Line %d", line);
243 : }
244 :
245 38 : fprintf(stderr, "\n\t%s\n", msgtext);
246 38 : fflush(stderr);
247 :
248 38 : return 0;
249 : }
|