new makefiles (part I)
[wxWidgets.git] / src / iodbc / execute.c
1 /*
2 * execute.c
3 *
4 * $Id$
5 *
6 * Invoke a query
7 *
8 * The iODBC driver manager.
9 *
10 * Copyright (C) 1995 by Ke Jin <kejin@empress.com>
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with this library; if not, write to the Free
24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27 #include "config.h"
28
29 #include "isql.h"
30 #include "isqlext.h"
31
32 #include "dlproc.h"
33
34 #include "herr.h"
35 #include "henv.h"
36 #include "hdbc.h"
37 #include "hstmt.h"
38
39 #include "itrace.h"
40
41 static void
42 do_cursoropen (STMT_t FAR * pstmt)
43 {
44 RETCODE retcode;
45 SWORD ncol;
46
47 pstmt->state = en_stmt_executed;
48
49 retcode = SQLNumResultCols (pstmt, &ncol);
50
51 if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
52 {
53 if (ncol)
54 {
55 pstmt->state = en_stmt_cursoropen;
56 pstmt->cursor_state = en_stmt_cursor_opened;
57 }
58 else
59 {
60 pstmt->state = en_stmt_executed;
61 pstmt->cursor_state = en_stmt_cursor_no;
62 }
63 }
64 }
65
66
67 RETCODE SQL_API
68 SQLExecute (HSTMT hstmt)
69 {
70 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
71 HPROC hproc = SQL_NULL_HPROC;
72 RETCODE retcode;
73
74 int sqlstat = en_00000;
75
76 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
77 {
78 return SQL_INVALID_HANDLE;
79 }
80
81 /* check state */
82 if (pstmt->asyn_on == en_NullProc)
83 {
84 switch (pstmt->state)
85 {
86 case en_stmt_allocated:
87 sqlstat = en_S1010;
88 break;
89
90 case en_stmt_executed:
91 if (!pstmt->prep_state)
92 {
93 sqlstat = en_S1010;
94 }
95 break;
96
97 case en_stmt_cursoropen:
98 if (!pstmt->prep_state)
99 {
100 sqlstat = en_S1010;
101 }
102 break;
103
104 case en_stmt_fetched:
105 case en_stmt_xfetched:
106 if (!pstmt->prep_state)
107 {
108 sqlstat = en_S1010;
109 }
110 else
111 {
112 sqlstat = en_24000;
113 }
114 break;
115
116 case en_stmt_needdata:
117 case en_stmt_mustput:
118 case en_stmt_canput:
119 sqlstat = en_S1010;
120 break;
121
122 default:
123 break;
124 }
125 }
126 else if (pstmt->asyn_on != en_Execute)
127 {
128 sqlstat = en_S1010;
129 }
130
131 if (sqlstat == en_00000)
132 {
133 hproc = _iodbcdm_getproc (pstmt->hdbc, en_Execute);
134
135 if (hproc == SQL_NULL_HPROC)
136 {
137 sqlstat = en_IM001;
138 }
139 }
140
141 if (sqlstat != en_00000)
142 {
143 PUSHSQLERR (pstmt->herr, sqlstat);
144
145 return SQL_ERROR;
146 }
147
148 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_Execute,
149 (pstmt->dhstmt))
150
151 /* stmt state transition */
152 if (pstmt->asyn_on == en_Execute)
153 {
154 switch (retcode)
155 {
156 case SQL_SUCCESS:
157 case SQL_SUCCESS_WITH_INFO:
158 case SQL_NEED_DATA:
159 case SQL_ERROR:
160 pstmt->asyn_on = en_NullProc;
161 break;
162
163 case SQL_STILL_EXECUTING:
164 default:
165 return retcode;
166 }
167 }
168
169 switch (pstmt->state)
170 {
171 case en_stmt_prepared:
172 switch (retcode)
173 {
174 case SQL_SUCCESS:
175 case SQL_SUCCESS_WITH_INFO:
176 do_cursoropen (hstmt);
177 break;
178
179 case SQL_NEED_DATA:
180 pstmt->state = en_stmt_needdata;
181 pstmt->need_on = en_Execute;
182 break;
183
184 case SQL_STILL_EXECUTING:
185 pstmt->asyn_on = en_Execute;
186 break;
187
188 default:
189 break;
190 }
191 break;
192
193 case en_stmt_executed:
194 switch (retcode)
195 {
196 case SQL_ERROR:
197 pstmt->state = en_stmt_allocated;
198 pstmt->cursor_state = en_stmt_cursor_no;
199 pstmt->prep_state = 0;
200 break;
201
202 case SQL_NEED_DATA:
203 pstmt->state = en_stmt_needdata;
204 pstmt->need_on = en_Execute;
205 break;
206
207 case SQL_STILL_EXECUTING:
208 pstmt->asyn_on = en_Execute;
209 break;
210
211 default:
212 break;
213 }
214 break;
215
216 default:
217 break;
218 }
219
220 return retcode;
221 }
222
223
224 RETCODE SQL_API
225 SQLExecDirect (
226 HSTMT hstmt,
227 UCHAR FAR * szSqlStr,
228 SDWORD cbSqlStr)
229 {
230 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
231 HPROC hproc = SQL_NULL_HPROC;
232
233 int sqlstat = en_00000;
234 RETCODE retcode = SQL_SUCCESS;
235
236 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
237 {
238 return SQL_INVALID_HANDLE;
239 }
240
241 /* check arguments */
242 if (szSqlStr == NULL)
243 {
244 sqlstat = en_S1009;
245 }
246 else if (cbSqlStr < 0 && cbSqlStr != SQL_NTS)
247 {
248 sqlstat = en_S1090;
249 }
250
251 if (sqlstat != en_00000)
252 {
253 PUSHSQLERR (pstmt->herr, sqlstat);
254
255 return SQL_ERROR;
256 }
257
258 /* check state */
259 if (pstmt->asyn_on == en_NullProc)
260 {
261 switch (pstmt->state)
262 {
263 case en_stmt_fetched:
264 case en_stmt_xfetched:
265 sqlstat = en_24000;
266 break;
267
268 case en_stmt_needdata:
269 case en_stmt_mustput:
270 case en_stmt_canput:
271 sqlstat = en_S1010;
272 break;
273
274 default:
275 break;
276 }
277 }
278 else if (pstmt->asyn_on != en_ExecDirect)
279 {
280 sqlstat = en_S1010;
281 }
282
283 if (sqlstat != en_00000)
284 {
285 PUSHSQLERR (pstmt->herr, sqlstat);
286
287 return SQL_ERROR;
288 }
289
290 hproc = _iodbcdm_getproc (pstmt->hdbc, en_ExecDirect);
291
292 if (hproc == SQL_NULL_HPROC)
293 {
294 PUSHSQLERR (pstmt->herr, en_IM001);
295
296 return SQL_ERROR;
297 }
298
299 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_ExecDirect,
300 (pstmt->dhstmt, szSqlStr, cbSqlStr))
301
302 /* stmt state transition */
303 if (pstmt->asyn_on == en_ExecDirect)
304 {
305 switch (retcode)
306 {
307 case SQL_SUCCESS:
308 case SQL_SUCCESS_WITH_INFO:
309 case SQL_NEED_DATA:
310 case SQL_ERROR:
311 pstmt->asyn_on = en_NullProc;
312 break;
313
314 case SQL_STILL_EXECUTING:
315 default:
316 return retcode;
317 }
318 }
319
320 if (pstmt->state <= en_stmt_executed)
321 {
322 switch (retcode)
323 {
324 case SQL_SUCCESS:
325 case SQL_SUCCESS_WITH_INFO:
326 do_cursoropen (hstmt);
327 break;
328
329 case SQL_NEED_DATA:
330 pstmt->state = en_stmt_needdata;
331 pstmt->need_on = en_ExecDirect;
332 break;
333
334 case SQL_STILL_EXECUTING:
335 pstmt->asyn_on = en_ExecDirect;
336 break;
337
338 case SQL_ERROR:
339 pstmt->state = en_stmt_allocated;
340 pstmt->cursor_state = en_stmt_cursor_no;
341 pstmt->prep_state = 0;
342 break;
343
344 default:
345 break;
346 }
347 }
348
349 return retcode;
350 }
351
352
353 RETCODE SQL_API
354 SQLPutData (
355 HSTMT hstmt,
356 PTR rgbValue,
357 SDWORD cbValue)
358 {
359 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
360 HPROC hproc;
361 RETCODE retcode;
362
363 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
364 {
365 return SQL_INVALID_HANDLE;
366 }
367
368 /* check argument value */
369 if (rgbValue == NULL &&
370 (cbValue != SQL_DEFAULT_PARAM && cbValue != SQL_NULL_DATA))
371 {
372 PUSHSQLERR (pstmt->herr, en_S1009);
373
374 return SQL_ERROR;
375 }
376
377 /* check state */
378 if (pstmt->asyn_on == en_NullProc)
379 {
380 if (pstmt->state <= en_stmt_xfetched)
381 {
382 PUSHSQLERR (pstmt->herr, en_S1010);
383
384 return SQL_ERROR;
385 }
386 }
387 else if (pstmt->asyn_on != en_PutData)
388 {
389 PUSHSQLERR (pstmt->herr, en_S1010);
390
391 return SQL_ERROR;
392 }
393
394 /* call driver */
395 hproc = _iodbcdm_getproc (pstmt->hdbc, en_PutData);
396
397 if (hproc == SQL_NULL_HPROC)
398 {
399 PUSHSQLERR (pstmt->herr, en_IM001);
400
401 return SQL_ERROR;
402 }
403
404 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_PutData,
405 (pstmt->dhstmt, rgbValue, cbValue))
406
407 /* state transition */
408 if (pstmt->asyn_on == en_PutData)
409 {
410 switch (retcode)
411 {
412 case SQL_SUCCESS:
413 case SQL_SUCCESS_WITH_INFO:
414 case SQL_ERROR:
415 pstmt->asyn_on = en_NullProc;
416 break;
417
418 case SQL_STILL_EXECUTING:
419 default:
420 return retcode;
421 }
422 }
423
424 /* must in mustput or canput states */
425 switch (retcode)
426 {
427 case SQL_SUCCESS:
428 case SQL_SUCCESS_WITH_INFO:
429 pstmt->state = en_stmt_canput;
430 break;
431
432 case SQL_ERROR:
433 switch (pstmt->need_on)
434 {
435 case en_ExecDirect:
436 pstmt->state = en_stmt_allocated;
437 pstmt->need_on = en_NullProc;
438 break;
439
440 case en_Execute:
441 if (pstmt->prep_state)
442 {
443 pstmt->state = en_stmt_prepared;
444 pstmt->need_on = en_NullProc;
445 }
446 break;
447
448 case en_SetPos:
449 /* Is this possible ???? */
450 pstmt->state = en_stmt_xfetched;
451 break;
452
453 default:
454 break;
455 }
456 break;
457
458 case SQL_STILL_EXECUTING:
459 pstmt->asyn_on = en_PutData;
460 break;
461
462 default:
463 break;
464 }
465
466 return retcode;
467 }
468
469
470 RETCODE SQL_API
471 SQLParamData (
472 HSTMT hstmt,
473 PTR FAR * prgbValue)
474 {
475 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
476 HPROC hproc;
477 RETCODE retcode;
478
479 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
480 {
481 return SQL_INVALID_HANDLE;
482 }
483
484 /* check argument */
485
486 /* check state */
487 if (pstmt->asyn_on == en_NullProc)
488 {
489 if (pstmt->state <= en_stmt_xfetched)
490 {
491 PUSHSQLERR (pstmt->herr, en_S1010);
492
493 return SQL_ERROR;
494 }
495 }
496 else if (pstmt->asyn_on != en_ParamData)
497 {
498 PUSHSQLERR (pstmt->herr, en_S1010);
499
500 return SQL_ERROR;
501 }
502
503 /* call driver */
504 hproc = _iodbcdm_getproc (pstmt->hdbc, en_ParamData);
505
506 if (hproc == SQL_NULL_HPROC)
507 {
508 PUSHSQLERR (pstmt->herr, en_IM001);
509
510 return SQL_ERROR;
511 }
512
513 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_ParamData,
514 (pstmt->dhstmt, prgbValue))
515
516 /* state transition */
517 if (pstmt->asyn_on == en_ParamData)
518 {
519 switch (retcode)
520 {
521 case SQL_SUCCESS:
522 case SQL_SUCCESS_WITH_INFO:
523 case SQL_ERROR:
524 pstmt->asyn_on = en_NullProc;
525 break;
526
527 case SQL_STILL_EXECUTING:
528 default:
529 return retcode;
530 }
531 }
532
533 if (pstmt->state < en_stmt_needdata)
534 {
535 return retcode;
536 }
537
538 switch (retcode)
539 {
540 case SQL_ERROR:
541 switch (pstmt->need_on)
542 {
543 case en_ExecDirect:
544 pstmt->state = en_stmt_allocated;
545 break;
546
547 case en_Execute:
548 pstmt->state = en_stmt_prepared;
549 break;
550
551 case en_SetPos:
552 pstmt->state = en_stmt_xfetched;
553 pstmt->cursor_state
554 = en_stmt_cursor_xfetched;
555 break;
556
557 default:
558 break;
559 }
560 pstmt->need_on = en_NullProc;
561 break;
562
563 case SQL_SUCCESS:
564 case SQL_SUCCESS_WITH_INFO:
565 switch (pstmt->state)
566 {
567 case en_stmt_needdata:
568 pstmt->state = en_stmt_mustput;
569 break;
570
571 case en_stmt_canput:
572 switch (pstmt->need_on)
573 {
574 case en_SetPos:
575 pstmt->state
576 = en_stmt_xfetched;
577 pstmt->cursor_state
578 = en_stmt_cursor_xfetched;
579 break;
580
581 case en_ExecDirect:
582 case en_Execute:
583 do_cursoropen (hstmt);
584 break;
585
586 default:
587 break;
588 }
589 break;
590
591 default:
592 break;
593 }
594 pstmt->need_on = en_NullProc;
595 break;
596
597 case SQL_NEED_DATA:
598 pstmt->state = en_stmt_mustput;
599 break;
600
601 default:
602 break;
603 }
604
605 return retcode;
606 }
607
608
609 RETCODE SQL_API
610 SQLNumParams (
611 HSTMT hstmt,
612 SWORD FAR * pcpar)
613 {
614 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
615 HPROC hproc;
616 RETCODE retcode;
617
618 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
619 {
620 return SQL_INVALID_HANDLE;
621 }
622
623 /* check argument */
624
625 /* check state */
626 if (pstmt->asyn_on == en_NullProc)
627 {
628 switch (pstmt->state)
629 {
630 case en_stmt_allocated:
631 case en_stmt_needdata:
632 case en_stmt_mustput:
633 case en_stmt_canput:
634 PUSHSQLERR (pstmt->herr, en_S1010);
635 return SQL_ERROR;
636
637 default:
638 break;
639 }
640 }
641 else if (pstmt->asyn_on != en_NumParams)
642 {
643 PUSHSQLERR (pstmt->herr, en_S1010);
644
645 return SQL_ERROR;
646 }
647
648 /* call driver */
649 hproc = _iodbcdm_getproc (pstmt->hdbc, en_NumParams);
650
651 if (hproc == SQL_NULL_HPROC)
652 {
653 PUSHSQLERR (pstmt->herr, en_IM001);
654
655 return SQL_ERROR;
656 }
657
658 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_NumParams,
659 (pstmt->dhstmt, pcpar))
660
661 /* state transition */
662 if (pstmt->asyn_on == en_NumParams)
663 {
664 switch (retcode)
665 {
666 case SQL_SUCCESS:
667 case SQL_SUCCESS_WITH_INFO:
668 case SQL_ERROR:
669 break;
670
671 default:
672 return retcode;
673 }
674 }
675
676 if (retcode == SQL_STILL_EXECUTING)
677 {
678 pstmt->asyn_on = en_NumParams;
679 }
680
681 return retcode;
682 }
683
684
685 RETCODE SQL_API
686 SQLDescribeParam (
687 HSTMT hstmt,
688 UWORD ipar,
689 SWORD FAR * pfSqlType,
690 UDWORD FAR * pcbColDef,
691 SWORD FAR * pibScale,
692 SWORD FAR * pfNullable)
693 {
694 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
695 HPROC hproc;
696 RETCODE retcode;
697
698 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
699 {
700 return SQL_INVALID_HANDLE;
701 }
702
703 /* check argument */
704 if (ipar == 0)
705 {
706 PUSHSQLERR (pstmt->herr, en_S1093);
707
708 return SQL_ERROR;
709 }
710
711 /* check state */
712 if (pstmt->asyn_on == en_NullProc)
713 {
714 switch (pstmt->state)
715 {
716 case en_stmt_allocated:
717 case en_stmt_needdata:
718 case en_stmt_mustput:
719 case en_stmt_canput:
720 PUSHSQLERR (pstmt->herr, en_S1010);
721 return SQL_ERROR;
722
723 default:
724 break;
725 }
726 }
727 else if (pstmt->asyn_on != en_DescribeParam)
728 {
729 PUSHSQLERR (pstmt->herr, en_S1010);
730
731 return SQL_ERROR;
732 }
733
734 /* call driver */
735 hproc = _iodbcdm_getproc (pstmt->hdbc, en_DescribeParam);
736
737 if (hproc == SQL_NULL_HPROC)
738 {
739 PUSHSQLERR (pstmt->herr, en_IM001);
740
741 return SQL_ERROR;
742 }
743
744 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_DescribeParam,
745 (pstmt->dhstmt, ipar, pfSqlType, pcbColDef, pibScale, pfNullable))
746
747 /* state transition */
748 if (pstmt->asyn_on == en_DescribeParam)
749 {
750 switch (retcode)
751 {
752 case SQL_SUCCESS:
753 case SQL_SUCCESS_WITH_INFO:
754 case SQL_ERROR:
755 break;
756
757 default:
758 return retcode;
759 }
760 }
761
762 if (retcode == SQL_STILL_EXECUTING)
763 {
764 pstmt->asyn_on = en_DescribeParam;
765 }
766
767 return retcode;
768 }