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