1 : /*
2 : * Purpose: Test remote procedure calls
3 : * Functions: dbretdata dbretlen dbretname dbretstatus dbrettype dbrpcinit dbrpcparam dbrpcsend
4 : */
5 :
6 : #if HAVE_CONFIG_H
7 : #include <config.h>
8 : #endif /* HAVE_CONFIG_H */
9 :
10 : #include <stdio.h>
11 :
12 : #if HAVE_STDLIB_H
13 : #include <stdlib.h>
14 : #endif /* HAVE_STDLIB_H */
15 :
16 : #if HAVE_STRING_H
17 : #include <string.h>
18 : #endif /* HAVE_STRING_H */
19 :
20 : #ifdef DBNTWIN32
21 : #include "winhackery.h"
22 : #endif
23 :
24 : #include <sqlfront.h>
25 : #include <sqldb.h>
26 :
27 : #include "common.h"
28 :
29 : static char software_version[] = "$Id: rpc.c,v 1.24.2.1 2006/07/11 18:39:38 jklowden Exp $";
30 : static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
31 :
32 : static char cmd[4096];
33 : static int init_proc(DBPROCESS * dbproc, const char *name);
34 :
35 : typedef struct {
36 : char *name, *value;
37 : int type, len;
38 : } RETPARAM;
39 :
40 : static RETPARAM* save_retparam(RETPARAM *param, char *name, char *value, int type, int len);
41 :
42 : static const char procedure_sql[] =
43 : "CREATE PROCEDURE %s \n"
44 : " @null_input varchar(30) OUTPUT \n"
45 : ", @first_type varchar(30) OUTPUT \n"
46 : ", @nullout int OUTPUT\n"
47 : ", @nrows int OUTPUT \n"
48 : ", @c varchar(20)\n"
49 : "AS \n"
50 : "BEGIN \n"
51 : "select @null_input = max(convert(varchar(30), name)) from systypes \n"
52 : "select @first_type = min(convert(varchar(30), name)) from systypes \n"
53 : "select name from sysobjects where 0=1\n"
54 : "select distinct convert(varchar(30), name) as 'type' from systypes \n"
55 : "where name in ('int', 'char', 'text') \n"
56 : "select @nrows = @@rowcount \n"
57 : "select distinct convert(varchar(30), name) as name from sysobjects where type = 'S' \n"
58 : "return 42 \n"
59 : "END \n";
60 :
61 : static int
62 : init_proc(DBPROCESS * dbproc, const char *name)
63 3 : {
64 3 : int res = 0;
65 :
66 3 : if (name[0] != '#') {
67 1 : fprintf(stdout, "Dropping procedure %s\n", name);
68 1 : add_bread_crumb();
69 1 : sprintf(cmd, "DROP PROCEDURE %s", name);
70 1 : dbcmd(dbproc, cmd);
71 1 : add_bread_crumb();
72 1 : dbsqlexec(dbproc);
73 1 : add_bread_crumb();
74 1 : while (dbresults(dbproc) != NO_MORE_RESULTS) {
75 : /* nop */
76 : }
77 1 : add_bread_crumb();
78 : }
79 :
80 3 : fprintf(stdout, "Creating procedure %s\n", name);
81 3 : sprintf(cmd, procedure_sql, name);
82 3 : dbcmd(dbproc, cmd);
83 3 : if (dbsqlexec(dbproc) == FAIL) {
84 1 : add_bread_crumb();
85 1 : res = 1;
86 1 : if (name[0] == '#')
87 1 : fprintf(stdout, "Failed to create procedure %s. Wrong permission or not MSSQL.\n", name);
88 : else
89 0 : fprintf(stdout, "Failed to create procedure %s. Wrong permission.\n", name);
90 : }
91 5 : while (dbresults(dbproc) != NO_MORE_RESULTS) {
92 : /* nop */
93 : }
94 3 : return res;
95 : }
96 :
97 : static RETPARAM*
98 : save_retparam(RETPARAM *param, char *name, char *value, int type, int len)
99 8 : {
100 8 : if (param->name)
101 6 : free(param->name);
102 8 : if (param->value)
103 6 : free(param->value);
104 :
105 8 : param->name = strdup(name);
106 8 : param->value = strdup(value);
107 :
108 8 : param->type = type;
109 8 : param->len = len;
110 :
111 8 : return param;
112 : }
113 :
114 : int
115 : main(int argc, char **argv)
116 2 : {
117 : LOGINREC *login;
118 : DBPROCESS *dbproc;
119 : RETPARAM save_param;
120 :
121 : int i, r;
122 : char teststr[1024];
123 2 : int failed = 0;
124 2 : char *retname = NULL;
125 2 : int rettype = 0, retlen = 0;
126 2 : int return_status = 0;
127 2 : char proc[] = "#t0022",
128 2 : param0[] = "@null_input",
129 2 : param1[] = "@first_type",
130 2 : param2[] = "@nullout",
131 2 : param3[] = "@nrows",
132 2 : param4[] = "@c";
133 2 : char *proc_name = proc;
134 :
135 : char param_data1[64];
136 : int param_data2;
137 : int param_data3;
138 : RETCODE erc, row_code;
139 2 : int num_resultset = 0;
140 2 : int num_empty_resultset = 0;
141 : static const char dashes5[] = "-----",
142 : dashes15[] = "---------------",
143 : dashes30[] = "------------------------------";
144 :
145 2 : set_malloc_options();
146 :
147 2 : memset(&save_param, 0, sizeof(save_param));
148 :
149 2 : read_login_info(argc, argv);
150 :
151 2 : fprintf(stdout, "Start\n");
152 2 : add_bread_crumb();
153 :
154 2 : dbinit();
155 :
156 2 : add_bread_crumb();
157 2 : dberrhandle(syb_err_handler);
158 2 : dbmsghandle(syb_msg_handler);
159 :
160 2 : fprintf(stdout, "About to logon\n");
161 :
162 2 : add_bread_crumb();
163 2 : login = dblogin();
164 2 : DBSETLPWD(login, PASSWORD);
165 2 : DBSETLUSER(login, USER);
166 2 : DBSETLAPP(login, "#t0022");
167 :
168 2 : fprintf(stdout, "About to open %s.%s\n", SERVER, DATABASE);
169 :
170 2 : add_bread_crumb();
171 2 : dbproc = dbopen(login, SERVER);
172 2 : if (strlen(DATABASE))
173 2 : dbuse(dbproc, DATABASE);
174 2 : add_bread_crumb();
175 2 : dbloginfree(login);
176 2 : add_bread_crumb();
177 :
178 2 : add_bread_crumb();
179 :
180 2 : if (init_proc(dbproc, proc_name))
181 1 : if (init_proc(dbproc, ++proc_name))
182 0 : exit(1);
183 :
184 : /* set up and send the rpc */
185 2 : erc = dbrpcinit(dbproc, proc_name, 0); /* no options */
186 2 : printf("executing dbrpcinit\n");
187 2 : if (erc == FAIL) {
188 0 : fprintf(stderr, "Failed: dbrpcinit\n");
189 0 : failed = 1;
190 : }
191 :
192 2 : printf("executing dbrpcparam\n");
193 2 : erc = dbrpcparam(dbproc, param0, DBRPCRETURN, SYBCHAR, /*maxlen= */ -1, /* datlen= */ 0, NULL);
194 2 : if (erc == FAIL) {
195 0 : fprintf(stderr, "Failed: dbrpcparam\n");
196 0 : failed = 1;
197 : }
198 :
199 2 : printf("executing dbrpcparam\n");
200 2 : erc = dbrpcparam(dbproc, param1, DBRPCRETURN, SYBCHAR, /*maxlen= */ sizeof(param_data1), /* datlen= */ 0, (BYTE *) & param_data1);
201 2 : if (erc == FAIL) {
202 0 : fprintf(stderr, "Failed: dbrpcparam\n");
203 0 : failed = 1;
204 : }
205 :
206 2 : printf("executing dbrpcparam\n");
207 2 : erc = dbrpcparam(dbproc, param2, DBRPCRETURN, SYBINT4, /*maxlen= */ -1, /* datalen= */ 0, (BYTE *) & param_data2);
208 2 : if (erc == FAIL) {
209 0 : fprintf(stderr, "Failed: dbrpcparam\n");
210 0 : failed = 1;
211 : }
212 :
213 2 : printf("executing dbrpcparam\n");
214 2 : erc = dbrpcparam(dbproc, param3, DBRPCRETURN, SYBINT4, /*maxlen= */ -1, /* datalen= */ -1, (BYTE *) & param_data3);
215 2 : if (erc == FAIL) {
216 0 : fprintf(stderr, "Failed: dbrpcparam\n");
217 0 : failed = 1;
218 : }
219 :
220 : /* test for strange parameters using input */
221 2 : printf("executing dbrpcparam\n");
222 2 : erc = dbrpcparam(dbproc, param4, 0, SYBVARCHAR, /*maxlen= */ 0, /* datalen= */ 0, NULL);
223 2 : if (erc == FAIL) {
224 0 : fprintf(stderr, "Failed: dbrpcparam\n");
225 0 : failed = 1;
226 : }
227 :
228 2 : printf("executing dbrpcsend\n");
229 2 : param_data3 = 0x11223344;
230 2 : erc = dbrpcsend(dbproc);
231 2 : if (erc == FAIL) {
232 0 : fprintf(stderr, "Failed: dbrpcsend\n");
233 0 : exit(1);
234 : }
235 :
236 : /* wait for it to execute */
237 2 : printf("executing dbsqlok\n");
238 2 : erc = dbsqlok(dbproc);
239 2 : if (erc == FAIL) {
240 0 : fprintf(stderr, "Failed: dbsqlok\n");
241 0 : exit(1);
242 : }
243 :
244 2 : add_bread_crumb();
245 :
246 : /* retrieve outputs per usual */
247 2 : r = 0;
248 10 : while ((erc = dbresults(dbproc)) != NO_MORE_RESULTS) {
249 6 : if (erc == SUCCEED) {
250 6 : const int ncols = dbnumcols(dbproc);
251 6 : int empty_resultset = 1;
252 6 : ++num_resultset;
253 6 : printf("bound 1 of %d columns ('%s') in result %d.\n", ncols, dbcolname(dbproc, 1), ++r);
254 6 : dbbind(dbproc, 1, STRINGBIND, -1, (BYTE *) teststr);
255 :
256 6 : printf("\t%s\n\t-----------\n", dbcolname(dbproc, 1));
257 6 : while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {
258 73 : empty_resultset = 0;
259 73 : if (row_code == REG_ROW) {
260 73 : printf("\t%s\n", teststr);
261 : } else {
262 : /* not supporting computed rows in this unit test */
263 0 : failed = 1;
264 0 : fprintf(stderr, "Failed. Expected a row\n");
265 0 : exit(1);
266 : }
267 : }
268 6 : if (empty_resultset)
269 2 : ++num_empty_resultset;
270 : } else {
271 0 : add_bread_crumb();
272 0 : fprintf(stderr, "Expected a result set.\n");
273 0 : exit(1);
274 : }
275 : } /* while dbresults */
276 :
277 : /* check return status */
278 2 : printf("retrieving return status...\n");
279 2 : if (dbhasretstat(dbproc) == TRUE) {
280 2 : printf("%d\n", return_status = dbretstatus(dbproc));
281 : } else {
282 0 : printf("none\n");
283 : }
284 :
285 : /*
286 : * Check output parameter values
287 : */
288 2 : if (dbnumrets(dbproc) < 4) { /* dbnumrets missed something */
289 0 : fprintf(stderr, "Expected 4 output parameters.\n");
290 0 : exit(1);
291 : }
292 2 : printf("retrieving output parameters...\n");
293 2 : printf("%-5s %-15s %5s %6s %-30s\n", "param", "name", "type", "length", "data");
294 2 : printf("%-5s %-15s %5s %5s- %-30s\n", dashes5, dashes15, dashes5, dashes5, dashes30);
295 10 : for (i = 1; i <= dbnumrets(dbproc); i++) {
296 8 : add_bread_crumb();
297 8 : retname = dbretname(dbproc, i);
298 8 : rettype = dbrettype(dbproc, i);
299 8 : retlen = dbretlen(dbproc, i);
300 8 : dbconvert(dbproc, rettype, dbretdata(dbproc, i), retlen, SYBVARCHAR, (BYTE*) teststr, -1);
301 8 : printf("%-5d %-15s %5d %6d %-30s\n", i, retname, rettype, retlen, teststr);
302 8 : add_bread_crumb();
303 :
304 8 : save_retparam(&save_param, retname, teststr, rettype, retlen);
305 : }
306 :
307 : /*
308 : * Test the last parameter for expected outcome
309 : */
310 2 : if ((save_param.name == NULL) || strcmp(save_param.name, param3)) {
311 0 : fprintf(stderr, "Expected retname to be '%s', got ", param3);
312 0 : if (save_param.name == NULL)
313 0 : fprintf(stderr, "<NULL> instead.\n");
314 : else
315 0 : fprintf(stderr, "'%s' instead.\n", save_param.name);
316 0 : exit(1);
317 : }
318 2 : if (strcmp(save_param.value, "3")) {
319 0 : fprintf(stderr, "Expected retdata to be 3.\n");
320 0 : exit(1);
321 : }
322 2 : if (save_param.type != SYBINT4) {
323 0 : fprintf(stderr, "Expected rettype to be SYBINT4 was %d.\n", save_param.type);
324 0 : exit(1);
325 : }
326 2 : if (save_param.len != 4) {
327 0 : fprintf(stderr, "Expected retlen to be 4.\n");
328 0 : exit(1);
329 : }
330 :
331 2 : if(42 != return_status) {
332 0 : fprintf(stderr, "Expected status to be 42.\n");
333 0 : exit(1);
334 : }
335 :
336 2 : printf("Good: Got 4 output parameters and 1 return status of %d.\n", return_status);
337 :
338 :
339 : /* Test number of result sets */
340 2 : if (num_resultset != 3) {
341 0 : fprintf(stderr, "Expected 3 resultset got %d.\n", num_resultset);
342 0 : exit(1);
343 : }
344 2 : if (num_empty_resultset != 1) {
345 0 : fprintf(stderr, "Expected an empty resultset got %d.\n", num_empty_resultset);
346 0 : exit(1);
347 : }
348 2 : printf("Good: Got %d resultsets and %d empty resultset.\n", num_resultset, num_empty_resultset);
349 :
350 2 : add_bread_crumb();
351 :
352 :
353 2 : fprintf(stdout, "Dropping procedure\n");
354 2 : add_bread_crumb();
355 2 : sprintf(cmd, "DROP PROCEDURE %s", proc_name);
356 2 : dbcmd(dbproc, cmd);
357 2 : add_bread_crumb();
358 2 : dbsqlexec(dbproc);
359 2 : add_bread_crumb();
360 4 : while (dbresults(dbproc) != NO_MORE_RESULTS) {
361 : /* nop */
362 : }
363 2 : add_bread_crumb();
364 2 : dbexit();
365 2 : add_bread_crumb();
366 :
367 2 : fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
368 2 : free_bread_crumb();
369 :
370 2 : if (save_param.name)
371 2 : free(save_param.name);
372 2 : if (save_param.value)
373 2 : free(save_param.value);
374 :
375 2 : return failed ? 1 : 0;
376 : }
|