]> git.saurik.com Git - wxWidgets.git/blob - src/iodbc/fetch.c
partial implementation of wxTLW's decorations
[wxWidgets.git] / src / iodbc / fetch.c
1 /*
2 * fetch.c
3 *
4 * $Id$
5 *
6 * Fetch query result
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 RETCODE SQL_API
42 SQLFetch (HSTMT hstmt)
43 {
44 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
45 HPROC hproc = SQL_NULL_HPROC;
46 RETCODE retcode;
47
48 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
49 {
50 return SQL_INVALID_HANDLE;
51 }
52
53 /* check state */
54 if (pstmt->asyn_on == en_NullProc)
55 {
56 switch (pstmt->state)
57 {
58 case en_stmt_allocated:
59 case en_stmt_prepared:
60 case en_stmt_xfetched:
61 case en_stmt_needdata:
62 case en_stmt_mustput:
63 case en_stmt_canput:
64 PUSHSQLERR (pstmt->herr, en_S1010);
65 return SQL_ERROR;
66
67 default:
68 break;
69 }
70 }
71 else if (pstmt->asyn_on != en_Fetch)
72 {
73 PUSHSQLERR (pstmt->herr, en_S1010);
74 return SQL_ERROR;
75 }
76
77 hproc = _iodbcdm_getproc (pstmt->hdbc, en_Fetch);
78
79 if (hproc == SQL_NULL_HPROC)
80 {
81 PUSHSQLERR (pstmt->herr, en_IM001);
82
83 return SQL_ERROR;
84 }
85
86 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_Fetch,
87 (pstmt->dhstmt))
88
89 /* state transition */
90 if (pstmt->asyn_on == en_Fetch)
91 {
92 switch (retcode)
93 {
94 case SQL_SUCCESS:
95 case SQL_SUCCESS_WITH_INFO:
96 case SQL_NO_DATA_FOUND:
97 case SQL_ERROR:
98 pstmt->asyn_on = en_NullProc;
99 break;
100
101 case SQL_STILL_EXECUTING:
102 default:
103 return retcode;
104 }
105 }
106
107 switch (pstmt->state)
108 {
109 case en_stmt_cursoropen:
110 case en_stmt_fetched:
111 switch (retcode)
112 {
113 case SQL_SUCCESS:
114 case SQL_SUCCESS_WITH_INFO:
115 pstmt->state = en_stmt_fetched;
116 pstmt->cursor_state = en_stmt_cursor_fetched;
117 break;
118
119 case SQL_NO_DATA_FOUND:
120 if (pstmt->prep_state)
121 {
122 pstmt->state = en_stmt_prepared;
123 }
124 else
125 {
126
127 pstmt->state = en_stmt_allocated;
128 }
129 pstmt->cursor_state = en_stmt_cursor_no;
130 break;
131
132 case SQL_STILL_EXECUTING:
133 pstmt->asyn_on = en_Fetch;
134 break;
135
136 default:
137 break;
138 }
139 break;
140
141 default:
142 break;
143 }
144
145 return retcode;
146 }
147
148
149 RETCODE SQL_API
150 SQLExtendedFetch (
151 HSTMT hstmt,
152 UWORD fFetchType,
153 SDWORD irow,
154 UDWORD FAR * pcrow,
155 UWORD FAR * rgfRowStatus)
156 {
157 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
158 HPROC hproc = SQL_NULL_HPROC;
159 RETCODE retcode;
160
161 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
162 {
163 return SQL_INVALID_HANDLE;
164 }
165
166 /* check fetch type */
167 if (fFetchType < SQL_FETCH_NEXT || fFetchType > SQL_FETCH_BOOKMARK)
168 {
169 /* Unlike MS driver manager(i.e. DM),
170 * we don't check driver's ODBC version
171 * against SQL_FETCH_RESUME (only 1.0)
172 * and SQL_FETCH_BOOKMARK (only 2.0).
173 */
174 PUSHSQLERR (pstmt->herr, en_S1106);
175
176 return SQL_ERROR;
177 }
178
179 /* check state */
180 if (pstmt->asyn_on == en_NullProc)
181 {
182 switch (pstmt->state)
183 {
184 case en_stmt_allocated:
185 case en_stmt_prepared:
186 case en_stmt_fetched:
187 case en_stmt_needdata:
188 case en_stmt_mustput:
189 case en_stmt_canput:
190 PUSHSQLERR (pstmt->herr, en_S1010);
191 return SQL_ERROR;
192
193 default:
194 break;
195 }
196 }
197 else if (pstmt->asyn_on != en_ExtendedFetch)
198 {
199 PUSHSQLERR (pstmt->herr, en_S1010);
200 return SQL_ERROR;
201 }
202
203 hproc = _iodbcdm_getproc (pstmt->hdbc, en_ExtendedFetch);
204
205 if (hproc == SQL_NULL_HPROC)
206 {
207 PUSHSQLERR (pstmt->herr, en_IM001);
208
209 return SQL_ERROR;
210 }
211
212 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_ExtendedFetch,
213 (pstmt->dhstmt, fFetchType, irow, pcrow, rgfRowStatus))
214
215 /* state transition */
216 if (pstmt->asyn_on == en_ExtendedFetch)
217 {
218 switch (retcode)
219 {
220 case SQL_SUCCESS:
221 case SQL_SUCCESS_WITH_INFO:
222 case SQL_NO_DATA_FOUND:
223 case SQL_ERROR:
224 pstmt->asyn_on = en_NullProc;
225 break;
226
227 case SQL_STILL_EXECUTING:
228 default:
229 return retcode;
230 }
231 }
232
233 switch (pstmt->state)
234 {
235 case en_stmt_cursoropen:
236 case en_stmt_xfetched:
237 switch (retcode)
238 {
239 case SQL_SUCCESS:
240 case SQL_SUCCESS_WITH_INFO:
241 case SQL_NO_DATA_FOUND:
242 pstmt->state = en_stmt_xfetched;
243 pstmt->cursor_state = en_stmt_cursor_xfetched;
244 break;
245
246 case SQL_STILL_EXECUTING:
247 pstmt->asyn_on = en_ExtendedFetch;
248 break;
249
250 default:
251 break;
252 }
253 break;
254
255 default:
256 break;
257 }
258
259 return retcode;
260 }
261
262
263 RETCODE SQL_API
264 SQLGetData (
265 HSTMT hstmt,
266 UWORD icol,
267 SWORD fCType,
268 PTR rgbValue,
269 SDWORD cbValueMax,
270 SDWORD FAR * pcbValue)
271 {
272 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
273 HPROC hproc;
274 RETCODE retcode;
275 int sqlstat = en_00000;
276
277 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
278 {
279 return SQL_INVALID_HANDLE;
280 }
281
282 /* check argument */
283 if (rgbValue == NULL)
284 {
285 sqlstat = en_S1009;
286 }
287 else if (cbValueMax < 0)
288 {
289 sqlstat = en_S1090;
290 }
291 else
292 {
293 switch (fCType)
294 {
295 case SQL_C_DEFAULT:
296 case SQL_C_CHAR:
297 case SQL_C_BINARY:
298 case SQL_C_BIT:
299 case SQL_C_TINYINT:
300 case SQL_C_STINYINT:
301 case SQL_C_UTINYINT:
302 case SQL_C_SHORT:
303 case SQL_C_SSHORT:
304 case SQL_C_USHORT:
305 case SQL_C_LONG:
306 case SQL_C_SLONG:
307 case SQL_C_ULONG:
308 case SQL_C_FLOAT:
309 case SQL_C_DOUBLE:
310 case SQL_C_DATE:
311 case SQL_C_TIME:
312 case SQL_C_TIMESTAMP:
313 break;
314
315 default:
316 sqlstat = en_S1003;
317 break;
318 }
319 }
320
321 if (sqlstat != en_00000)
322 {
323 PUSHSQLERR (pstmt->herr, sqlstat);
324
325 return SQL_ERROR;
326 }
327
328 /* check state */
329 if (pstmt->asyn_on == en_NullProc)
330 {
331 switch (pstmt->state)
332 {
333 case en_stmt_allocated:
334 case en_stmt_prepared:
335 case en_stmt_needdata:
336 case en_stmt_mustput:
337 case en_stmt_canput:
338 sqlstat = en_S1010;
339 break;
340
341 case en_stmt_executed:
342 case en_stmt_cursoropen:
343 sqlstat = en_24000;
344 break;
345
346 default:
347 break;
348 }
349 }
350 else if (pstmt->asyn_on != en_GetData)
351 {
352 sqlstat = en_S1010;
353 }
354
355 if (sqlstat != en_00000)
356 {
357 PUSHSQLERR (pstmt->herr, sqlstat);
358
359 return SQL_ERROR;
360 }
361
362 /* call driver */
363 hproc = _iodbcdm_getproc (pstmt->hdbc, en_GetData);
364
365 if (hproc == SQL_NULL_HPROC)
366 {
367 PUSHSQLERR (pstmt->herr, en_IM001);
368
369 return SQL_ERROR;
370 }
371
372 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_GetData,
373 (pstmt->dhstmt, icol, fCType, rgbValue, cbValueMax, pcbValue))
374
375 /* state transition */
376 if (pstmt->asyn_on == en_GetData)
377 {
378 switch (retcode)
379 {
380 case SQL_SUCCESS:
381 case SQL_SUCCESS_WITH_INFO:
382 case SQL_NO_DATA_FOUND:
383 case SQL_ERROR:
384 pstmt->asyn_on = en_NullProc;
385 break;
386
387 case SQL_STILL_EXECUTING:
388 default:
389 return retcode;
390 }
391 }
392
393 switch (pstmt->state)
394 {
395 case en_stmt_fetched:
396 case en_stmt_xfetched:
397 if (retcode == SQL_STILL_EXECUTING)
398 {
399 pstmt->asyn_on = en_GetData;
400 break;
401 }
402 break;
403
404 default:
405 break;
406 }
407
408 return retcode;
409 }
410
411
412 RETCODE SQL_API
413 SQLMoreResults (HSTMT hstmt)
414 {
415 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
416 HPROC hproc;
417 RETCODE retcode;
418
419 if (hstmt == SQL_NULL_HSTMT
420 || pstmt->hdbc == SQL_NULL_HDBC)
421 {
422 return SQL_INVALID_HANDLE;
423 }
424
425 /* check state */
426 if (pstmt->asyn_on == en_NullProc)
427 {
428 switch (pstmt->state)
429 {
430 case en_stmt_allocated:
431 case en_stmt_prepared:
432 return SQL_NO_DATA_FOUND;
433
434 case en_stmt_needdata:
435 case en_stmt_mustput:
436 case en_stmt_canput:
437 PUSHSQLERR (pstmt->herr, en_S1010);
438 return SQL_ERROR;
439
440 default:
441 break;
442 }
443 }
444 else if (pstmt->asyn_on != en_MoreResults)
445 {
446 PUSHSQLERR (pstmt->herr, en_S1010);
447
448 return SQL_ERROR;
449 }
450
451 /* call driver */
452 hproc = _iodbcdm_getproc (pstmt->hdbc, en_MoreResults);
453
454 if (hproc == SQL_NULL_HPROC)
455 {
456 PUSHSQLERR (pstmt->herr, en_IM001);
457
458 return SQL_ERROR;
459 }
460
461 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_MoreResults,
462 (pstmt->dhstmt))
463
464 /* state transition */
465 if (pstmt->asyn_on == en_MoreResults)
466 {
467 switch (retcode)
468 {
469 case SQL_SUCCESS:
470 case SQL_SUCCESS_WITH_INFO:
471 case SQL_NO_DATA_FOUND:
472 case SQL_ERROR:
473 pstmt->asyn_on = en_NullProc;
474 break;
475
476 case SQL_STILL_EXECUTING:
477 default:
478 return retcode;
479 }
480 }
481
482 switch (pstmt->state)
483 {
484 case en_stmt_allocated:
485 case en_stmt_prepared:
486 /* driver should return SQL_NO_DATA_FOUND */
487 break;
488
489 case en_stmt_executed:
490 if (retcode == SQL_NO_DATA_FOUND)
491 {
492 if (pstmt->prep_state)
493 {
494 pstmt->state = en_stmt_prepared;
495 }
496 else
497 {
498 pstmt->state = en_stmt_allocated;
499 }
500 }
501 else if (retcode == SQL_STILL_EXECUTING)
502 {
503 pstmt->asyn_on = en_MoreResults;
504 }
505 break;
506
507 case en_stmt_cursoropen:
508 case en_stmt_fetched:
509 case en_stmt_xfetched:
510 if (retcode == SQL_SUCCESS)
511 {
512 break;
513 }
514 else if (retcode == SQL_NO_DATA_FOUND)
515 {
516 if (pstmt->prep_state)
517 {
518 pstmt->state = en_stmt_prepared;
519 }
520 else
521 {
522 pstmt->state = en_stmt_allocated;
523 }
524 }
525 else if (retcode == SQL_STILL_EXECUTING)
526 {
527 pstmt->asyn_on = en_MoreResults;
528 }
529 break;
530
531 default:
532 break;
533 }
534
535 return retcode;
536 }
537
538
539 RETCODE SQL_API
540 SQLSetPos (
541 HSTMT hstmt,
542 UWORD irow,
543 UWORD fOption,
544 UWORD fLock)
545 {
546 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
547 HPROC hproc;
548 RETCODE retcode;
549 int sqlstat = en_00000;
550
551 if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
552 {
553 return SQL_INVALID_HANDLE;
554 }
555
556 /* check argument value */
557 if (fOption > SQL_ADD || fLock > SQL_LOCK_UNLOCK)
558 {
559 PUSHSQLERR (pstmt->herr, en_S1009);
560 }
561
562 /* check state */
563 if (pstmt->asyn_on == en_NullProc)
564 {
565 switch (pstmt->state)
566 {
567 case en_stmt_allocated:
568 case en_stmt_prepared:
569 case en_stmt_fetched:
570 case en_stmt_needdata:
571 case en_stmt_mustput:
572 case en_stmt_canput:
573 sqlstat = en_S1010;
574 break;
575
576 case en_stmt_executed:
577 case en_stmt_cursoropen:
578 sqlstat = en_24000;
579 break;
580
581 default:
582 break;
583 }
584 }
585 else if (pstmt->asyn_on != en_SetPos)
586 {
587 sqlstat = en_S1010;
588 }
589
590 if (sqlstat != en_00000)
591 {
592 PUSHSQLERR (pstmt->herr, sqlstat);
593
594 return SQL_ERROR;
595 }
596
597 /* call driver */
598 hproc = _iodbcdm_getproc (pstmt->hdbc, en_SetPos);
599
600 if (hproc == SQL_NULL_HPROC)
601 {
602 PUSHSQLERR (pstmt->herr, en_IM001);
603
604 return SQL_ERROR;
605 }
606
607 CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_SetPos,
608 (pstmt->dhstmt, irow, fOption, fLock))
609
610 /* state transition */
611 if (pstmt->asyn_on == en_SetPos)
612 {
613 switch (retcode)
614 {
615 case SQL_SUCCESS:
616 case SQL_SUCCESS_WITH_INFO:
617 case SQL_NEED_DATA:
618 case SQL_ERROR:
619 pstmt->asyn_on = en_NullProc;
620 break;
621
622 case SQL_STILL_EXECUTING:
623 default:
624 return retcode;
625 }
626 }
627
628 /* now, the only possible init state is 'xfetched' */
629 switch (retcode)
630 {
631 case SQL_SUCCESS:
632 case SQL_SUCCESS_WITH_INFO:
633 break;
634
635 case SQL_NEED_DATA:
636 pstmt->state = en_stmt_needdata;
637 pstmt->need_on = en_SetPos;
638 break;
639
640 case SQL_STILL_EXECUTING:
641 pstmt->asyn_on = en_SetPos;
642 break;
643
644 default:
645 break;
646 }
647
648 return retcode;
649 }