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 204 : prdbretcode(int retcode)
31 : {
32 : static char unknown[24];
33 204 : switch(retcode) {
34 : case REG_ROW: return "REG_ROW/MORE_ROWS";
35 172 : 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 202 : prretcode(int retcode)
48 : {
49 : static char unknown[24];
50 202 : switch(retcode) {
51 : case SUCCEED: return "SUCCEED";
52 8 : case FAIL: return "FAIL";
53 110 : 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 80 : query(const char comment[])
62 : {
63 80 : if (comment)
64 32 : printf("%s\n", comment);
65 80 : sql_cmd(dbproc);
66 80 : dbsqlexec(dbproc);
67 80 : while (dbresults(dbproc) == SUCCEED) {
68 : /* nop */
69 : }
70 80 : }
71 :
72 : typedef const char* (*prfunc)(int);
73 :
74 : static void
75 406 : check_state(const char name[], prfunc print, int erc)
76 : {
77 406 : printf("State %-15s %-20s ", name, print(erc));
78 406 : if (dbnumcols(dbproc) > 0)
79 302 : printf("COLS(%d) ", dbnumcols(dbproc));
80 : /* row count */
81 406 : if (dbcount(dbproc) >= 0)
82 70 : printf("ROWS(%d) ", (int) dbcount(dbproc));
83 406 : silent = 1;
84 406 : if (dbdata(dbproc, 1))
85 104 : printf("DATA ");
86 406 : silent = 0;
87 : /* if status present */
88 406 : if (dbretstatus(dbproc) == TRUE)
89 0 : printf("STATUS %d ", (int) dbretstatus(dbproc));
90 : /* if parameter present */
91 406 : 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 406 : if (check_idle) {
98 48 : silent = 1;
99 48 : dbcmd(dbproc, "declare @i int ");
100 48 : if (FAIL != dbsqlexec(dbproc))
101 16 : printf("IDLE ");
102 48 : silent = 0;
103 : }
104 406 : printf("\n");
105 406 : }
106 :
107 : static void
108 48 : do_test(const char comment[])
109 : {
110 : int ret;
111 48 : prfunc print_with = NULL;
112 :
113 48 : if (comment)
114 48 : printf("%s\n", comment);
115 48 : sql_cmd(dbproc);
116 :
117 48 : check_state("sqlexec ", prretcode, dbsqlexec(dbproc));
118 :
119 48 : check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
120 48 : check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
121 48 : check_state("results ", prretcode, dbresults(dbproc));
122 48 : check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
123 48 : check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
124 :
125 48 : check_idle = 0;
126 : for (;;) {
127 58 : ret = dbresults(dbproc);
128 58 : check_state("results ", prretcode, ret);
129 58 : if (ret != SUCCEED) {
130 48 : print_with = prretcode;
131 : break;
132 : }
133 :
134 : do {
135 12 : ret = dbnextrow(dbproc);
136 12 : check_state("nextrow ", prdbretcode, ret);
137 12 : } while (ret == REG_ROW);
138 : print_with = prdbretcode;
139 : }
140 48 : check_state("more results?", print_with, ret);
141 48 : }
142 :
143 : int
144 8 : main(int argc, char *argv[])
145 : {
146 : static const int invalid_column_name = 207;
147 : LOGINREC *login; /* Our login information. */
148 : int i;
149 :
150 8 : setbuf(stdout, NULL);
151 8 : read_login_info(argc, argv);
152 :
153 8 : if (dbinit() == FAIL)
154 0 : exit(1);
155 :
156 8 : dberrhandle(err_handler);
157 8 : dbmsghandle(msg_handler);
158 :
159 : #if 0
160 : /*
161 : * FIXME: Should be able to use the common err/msg handlers, but something about
162 : * the IDLE checking causes them to fail. Not sure about purpose of IDLE checking.
163 : * -- jkl January 2009
164 : */
165 : dberrhandle(syb_err_handler);
166 : dbmsghandle(syb_msg_handler);
167 : #endif
168 :
169 8 : login = dblogin();
170 8 : DBSETLUSER(login, USER);
171 8 : DBSETLPWD(login, PASSWORD);
172 8 : DBSETLAPP(login, "done_handling");
173 :
174 8 : dbproc = dbopen(login, SERVER);
175 8 : dbloginfree(login);
176 8 : if (!dbproc)
177 0 : exit(1);
178 8 : if (strlen(DATABASE))
179 8 : dbuse(dbproc, DATABASE);
180 :
181 48 : for (i=0; i < 6; i++)
182 48 : query(NULL);
183 : #if 0
184 : check_state("setup done ", prretcode, erc);
185 :
186 : printf("wasting results\n");
187 : while ((erc = dbresults(dbproc)) == SUCCEED) {
188 : while (dbnextrow(dbproc) == REG_ROW); /* no-op */
189 : }
190 : #endif
191 8 : check_idle = 1;
192 :
193 8 : do_test("normal row with rowcount on");
194 8 : query("turn rowcount off");
195 8 : do_test("normal row with rowcount off");
196 8 : query("turn rowcount back on");
197 8 : do_test("normal row without rows");
198 8 : dbsetuserdata(dbproc, (BYTE*) &invalid_column_name);
199 8 : do_test("error query");
200 8 : do_test("stored procedure call with output parameters");
201 :
202 8 : do_test("execute done2");
203 :
204 8 : query("drop done_test");
205 :
206 8 : query("drop done_test2");
207 :
208 8 : dbexit();
209 : return 0;
210 : }
211 :
212 : static int
213 40 : err_handler(DBPROCESS * dbproc TDS_UNUSED, int severity, int dberr TDS_UNUSED, int oserr, char *dberrstr, char *oserrstr)
214 : {
215 40 : if (silent)
216 : return INT_CANCEL;
217 :
218 8 : fflush(stdout);
219 8 : fprintf(stderr, "DB-Library error (severity %d):\n\t%s\n", severity, dberrstr);
220 :
221 8 : if (oserr != DBNOERR)
222 0 : fprintf(stderr, "Operating-system error:\n\t%s\n", oserrstr ? oserrstr : "(null)");
223 8 : fflush(stderr);
224 :
225 8 : return INT_CANCEL;
226 : }
227 :
228 : static int
229 30 : msg_handler(DBPROCESS * dbproc TDS_UNUSED, DBINT msgno, int msgstate, int severity,
230 : char *msgtext, char *srvname, char *procname, int line)
231 : {
232 30 : if (silent)
233 : return 0;
234 :
235 30 : fflush(stdout);
236 30 : fprintf(stderr, "Msg %d, Level %d, State %d\n", (int) msgno, severity, msgstate);
237 :
238 30 : if (strlen(srvname) > 0)
239 30 : fprintf(stderr, "Server '%s', ", srvname);
240 30 : if (procname && strlen(procname) > 0) {
241 0 : fprintf(stderr, "Procedure '%s', ", procname);
242 0 : if (line > 0)
243 0 : fprintf(stderr, "Line %d", line);
244 : }
245 :
246 30 : fprintf(stderr, "\n\t%s\n", msgtext);
247 30 : fflush(stderr);
248 :
249 30 : return 0;
250 : }
|