]> git.saurik.com Git - wxWidgets.git/blob - src/iodbc/hstmt.c
added ODBC support
[wxWidgets.git] / src / iodbc / hstmt.c
1 /** Query statement object management functions
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 SQLAllocStmt (
31 HDBC hdbc,
32 HSTMT FAR* phstmt )
33 {
34 DBC_t FAR* pdbc = (DBC_t FAR*)hdbc;
35 STMT_t FAR* pstmt = NULL;
36 HPROC hproc = SQL_NULL_HPROC;
37 RETCODE retcode = SQL_SUCCESS;
38
39 #if (ODBCVER >= 0x0300)
40 if( hdbc == SQL_NULL_HDBC
41 || pdbc->type != SQL_HANDLE_DBC )
42 #else
43 if( hdbc == SQL_NULL_HDBC )
44 #endif
45 {
46 return SQL_INVALID_HANDLE;
47 }
48
49 if( phstmt == NULL )
50 {
51 PUSHSQLERR ( pdbc->herr, en_S1009 );
52
53 return SQL_ERROR;
54 }
55
56 /* check state */
57 switch( pdbc->state )
58 {
59 case en_dbc_connected:
60 case en_dbc_hstmt:
61 break;
62
63 case en_dbc_allocated:
64 case en_dbc_needdata:
65 PUSHSQLERR ( pdbc->herr, en_08003 );
66 *phstmt = SQL_NULL_HSTMT;
67 return SQL_ERROR;
68
69 default:
70 return SQL_INVALID_HANDLE;
71 }
72
73 pstmt = (STMT_t FAR*)MEM_ALLOC(sizeof(STMT_t));
74
75 if( pstmt == NULL )
76 {
77 PUSHSQLERR ( pdbc->herr, en_S1001 );
78 *phstmt = SQL_NULL_HSTMT;
79
80 return SQL_ERROR;
81 }
82
83 #if (ODBCVER >= 0x0300)
84 pstmt->type = SQL_HANDLE_STMT;
85 #endif
86 /* initiate the object */
87 pstmt->herr = SQL_NULL_HERR;
88 pstmt->hdbc = hdbc;
89 pstmt->state = en_stmt_allocated;
90 pstmt->cursor_state = en_stmt_cursor_no;
91 pstmt->prep_state = 0;
92 pstmt->asyn_on = en_NullProc;
93 pstmt->need_on = en_NullProc;
94
95 /* call driver's function */
96 #if (ODBCVER >= 0x0300)
97 hproc = _iodbcdm_getproc( hdbc, en_AllocHandle );
98
99 if( hproc )
100 {
101 CALL_DRIVER ( pstmt->hdbc, hdbc, retcode, hproc,
102 en_AllocHandle, (
103 SQL_HANDLE_STMT,
104 pdbc->dhdbc,
105 &(pstmt->dhstmt) ) )
106 }
107 else
108 #endif
109 {
110 hproc = _iodbcdm_getproc( hdbc, en_AllocStmt );
111
112 if( hproc == SQL_NULL_HPROC )
113 {
114 PUSHSQLERR ( pstmt->herr, en_IM001 );
115 *phstmt = SQL_NULL_HSTMT;
116 MEM_FREE ( pstmt );
117
118 return SQL_ERROR;
119 }
120
121 CALL_DRIVER ( hdbc, retcode, hproc, en_AllocStmt, (
122 pdbc->dhdbc, &(pstmt->dhstmt) ) )
123 }
124
125 if( retcode != SQL_SUCCESS
126 && retcode != SQL_SUCCESS_WITH_INFO )
127 {
128 *phstmt = SQL_NULL_HSTMT;
129 MEM_FREE ( pstmt );
130
131 return retcode;
132 }
133
134 /* insert into list */
135 pstmt->next = pdbc->hstmt;
136 pdbc->hstmt = pstmt;
137
138 *phstmt = (HSTMT)pstmt;
139
140 /* state transition */
141 pdbc->state = en_dbc_hstmt;
142
143 return SQL_SUCCESS;
144 }
145
146 RETCODE _iodbcdm_dropstmt( HSTMT hstmt )
147 {
148 STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
149 STMT_t FAR* tpstmt;
150 DBC_t FAR* pdbc;
151
152 if( hstmt == SQL_NULL_HSTMT )
153 {
154 return SQL_INVALID_HANDLE;
155 }
156
157 pdbc = (DBC_t FAR*)(pstmt->hdbc);
158
159 for(tpstmt = (STMT_t FAR*)pdbc->hstmt;
160 tpstmt != NULL;
161 tpstmt = tpstmt->next )
162 {
163 if(tpstmt == pstmt)
164 {
165 pdbc->hstmt = (HSTMT)pstmt->next;
166 break;
167 }
168
169 if(tpstmt->next == pstmt)
170 {
171 tpstmt->next = pstmt->next;
172 break;
173 }
174 }
175
176 if( tpstmt == NULL )
177 {
178 return SQL_INVALID_HANDLE;
179 }
180
181 _iodbcdm_freesqlerrlist(pstmt->herr);
182 MEM_FREE(hstmt);
183
184 return SQL_SUCCESS;
185 }
186
187 RETCODE SQL_API SQLfreestmt (
188 HSTMT hstmt,
189 UWORD fOption )
190 {
191 STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
192 STMT_t FAR* tpstmt;
193 DBC_t FAR* pdbc;
194
195 HPROC hproc = SQL_NULL_HPROC;
196 RETCODE retcode;
197
198 if( hstmt == SQL_NULL_HSTMT
199 || pstmt->hdbc == SQL_NULL_HDBC )
200 {
201 return SQL_INVALID_HANDLE;
202 }
203
204 pdbc = (DBC_t FAR*)(pstmt->hdbc);
205
206 /* check option */
207 switch( fOption )
208 {
209 case SQL_DROP:
210 case SQL_CLOSE:
211 case SQL_UNBIND:
212 case SQL_RESET_PARAMS:
213 break;
214
215 default:
216 PUSHSQLERR ( pstmt->herr, en_S1092 );
217 return SQL_ERROR;
218 }
219
220 /* check state */
221 if( pstmt->state >= en_stmt_needdata
222 || pstmt->asyn_on != en_NullProc )
223 {
224 PUSHSQLERR ( pstmt->herr, en_S1010 );
225
226 return SQL_ERROR;
227 }
228
229 hproc = SQL_NULL_HPROC;
230
231 #if (ODBCVER >= 0x0300)
232 if( fOption == SQL_DROP )
233 {
234 hproc = _iodbcdm_getproc( pstmt->hdbc, en_FreeHandle );
235
236 if( hproc )
237 {
238 CALL_DRIVER( pstmt->hdbc, retcode, hproc, en_FreeHandle, (
239 SQL_HANDLE_STMT, pstmt->dhstmt )
240 }
241 }
242 #endif
243
244 if( hproc == SQL_NULL_HPROC )
245 {
246 hproc = _iodbcdm_getproc( pstmt->hdbc, en_FreeStmt);
247
248 if( hproc == SQL_NULL_HPROC )
249 {
250 PUSHSQLERR ( pstmt->herr, en_IM001 );
251
252 return SQL_ERROR;
253 }
254
255 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_FreeStmt, (
256 pstmt->dhstmt, fOption) )
257 }
258
259 if( retcode != SQL_SUCCESS
260 && retcode != SQL_SUCCESS_WITH_INFO )
261 {
262 return retcode;
263 }
264
265 /* state transition */
266 switch( fOption )
267 {
268 case SQL_DROP:
269 /* delet this object (ignore return) */
270 _iodbcdm_dropstmt( hstmt );
271 break;
272
273 case SQL_CLOSE:
274 pstmt->cursor_state = en_stmt_cursor_no;
275 /* This means cursor name set by
276 * SQLSetCursorName() call will also
277 * be erased.
278 */
279
280 switch( pstmt->state )
281 {
282 case en_stmt_allocated:
283 case en_stmt_prepared:
284 break;
285
286 case en_stmt_executed:
287 case en_stmt_cursoropen:
288 case en_stmt_fetched:
289 case en_stmt_xfetched:
290 if( pstmt->prep_state )
291 {
292 pstmt->state =
293 en_stmt_prepared;
294 }
295 else
296 {
297 pstmt->state =
298 en_stmt_allocated;
299 }
300 break;
301
302 default:
303 break;
304 }
305 break;
306
307 case SQL_UNBIND:
308 case SQL_RESET_PARAMS:
309 default:
310 break;
311 }
312
313 return retcode;
314 }
315
316 RETCODE SQL_API SQLSetStmtOption (
317 HSTMT hstmt,
318 UWORD fOption,
319 UDWORD vParam )
320 {
321 STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
322 HPROC hproc;
323 int sqlstat = en_00000;
324 RETCODE retcode;
325
326 if( hstmt == SQL_NULL_HSTMT
327 || pstmt->hdbc == SQL_NULL_HDBC )
328 {
329 return SQL_INVALID_HANDLE;
330 }
331
332 /* check option */
333 if(/* fOption < SQL_STMT_OPT_MIN || */
334 fOption > SQL_STMT_OPT_MAX )
335 {
336 PUSHSQLERR ( pstmt->herr, en_S1092 );
337
338 return SQL_ERROR;
339 }
340
341 if( fOption == SQL_CONCURRENCY
342 || fOption == SQL_CURSOR_TYPE
343 || fOption == SQL_SIMULATE_CURSOR
344 || fOption == SQL_USE_BOOKMARKS )
345 {
346 if( pstmt->asyn_on != en_NullProc )
347 {
348 if( pstmt->prep_state )
349 {
350 sqlstat = en_S1011;
351 }
352 }
353 else
354 {
355 switch( pstmt->state )
356 {
357 case en_stmt_prepared:
358 sqlstat = en_S1011;
359 break;
360
361 case en_stmt_executed:
362 case en_stmt_cursoropen:
363 case en_stmt_fetched:
364 case en_stmt_xfetched:
365 sqlstat = en_24000;
366 break;
367
368 case en_stmt_needdata:
369 case en_stmt_mustput:
370 case en_stmt_canput:
371 if( pstmt->prep_state )
372 {
373 sqlstat = en_S1011;
374 }
375 break;
376
377 default:
378 break;
379 }
380 }
381 }
382 else
383 {
384 if( pstmt->asyn_on != en_NullProc )
385 {
386 if( ! pstmt->prep_state )
387 {
388 sqlstat = en_S1010;
389 }
390 }
391 else
392 {
393 if( pstmt->state >= en_stmt_needdata )
394 {
395 sqlstat = en_S1010;
396 }
397 }
398 }
399
400 if( sqlstat != en_00000 )
401 {
402 PUSHSQLERR ( pstmt->herr, sqlstat );
403
404 return SQL_ERROR;
405 }
406
407 hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetStmtOption );
408
409 if( hproc == SQL_NULL_HPROC )
410 {
411 PUSHSQLERR ( pstmt->herr, en_IM001 );
412
413 return SQL_ERROR;
414 }
415
416 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetStmtOption, (
417 pstmt->dhstmt, fOption, vParam ) )
418
419 #if 0
420 retcode = hproc ( pstmt->dhstmt, fOption, vParam );
421 #endif
422
423 return retcode;
424 }
425
426 RETCODE SQL_API SQLGetStmtOption (
427 HSTMT hstmt,
428 UWORD fOption,
429 PTR pvParam )
430 {
431 STMT_t FAR* pstmt = (STMT_t*)hstmt;
432 HPROC hproc;
433 int sqlstat = en_00000;
434 RETCODE retcode;
435
436 if( hstmt == SQL_NULL_HSTMT
437 || pstmt->hdbc == SQL_NULL_HDBC )
438 {
439 return SQL_INVALID_HANDLE;
440 }
441
442 /* check option */
443 if( /* fOption < SQL_STMT_OPT_MIN || */
444 fOption > SQL_STMT_OPT_MAX )
445 {
446 PUSHSQLERR ( pstmt->herr, en_S1092 );
447
448 return SQL_ERROR;
449 }
450
451 /* check state */
452 if( pstmt->state >= en_stmt_needdata
453 || pstmt->asyn_on != en_NullProc )
454 {
455 sqlstat = en_S1010;
456 }
457 else
458 {
459 switch( pstmt->state )
460 {
461 case en_stmt_allocated:
462 case en_stmt_prepared:
463 case en_stmt_executed:
464 case en_stmt_cursoropen:
465 if( fOption == SQL_ROW_NUMBER
466 || fOption == SQL_GET_BOOKMARK )
467 {
468 sqlstat = en_24000;
469 }
470 break;
471
472 default:
473 break;
474 }
475 }
476
477 if( sqlstat != en_00000 )
478 {
479 PUSHSQLERR ( pstmt->herr, sqlstat );
480
481 return SQL_ERROR;
482 }
483
484 hproc = _iodbcdm_getproc( pstmt->hdbc, en_GetStmtOption);
485
486 if( hproc == SQL_NULL_HPROC )
487 {
488 PUSHSQLERR ( pstmt->herr, en_IM001 );
489 return SQL_ERROR;
490 }
491
492 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_GetStmtOption, (
493 pstmt->dhstmt, fOption, pvParam ) )
494
495 #if 0
496 retcode = hproc ( pstmt->dhstmt, fOption, pvParam );
497 #endif
498
499 return retcode;
500 }
501
502 RETCODE SQL_API SQLCancel ( HSTMT hstmt )
503 {
504 STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
505 HPROC hproc;
506 RETCODE retcode;
507
508 if( hstmt == SQL_NULL_HSTMT
509 || pstmt->hdbc == SQL_NULL_HDBC )
510 {
511 return SQL_INVALID_HANDLE;
512 }
513
514 /* check argument */
515 /* check state */
516
517 /* call driver */
518 hproc = _iodbcdm_getproc( pstmt->hdbc, en_Cancel );
519
520 if( hproc == SQL_NULL_HPROC )
521 {
522 PUSHSQLERR ( pstmt->herr, en_IM001 );
523
524 return SQL_ERROR;
525 }
526
527 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_Cancel, (pstmt->dhstmt) )
528
529 #if 0
530 retcode = hproc ( pstmt->dhstmt );
531 #endif
532
533 /* state transition */
534 if( retcode != SQL_SUCCESS
535 && retcode != SQL_SUCCESS_WITH_INFO )
536 {
537 return retcode;
538 }
539
540 switch( pstmt->state )
541 {
542 case en_stmt_allocated:
543 case en_stmt_prepared:
544 break;
545
546 case en_stmt_executed:
547 if( pstmt->prep_state )
548 {
549 pstmt->state = en_stmt_prepared;
550 }
551 else
552 {
553 pstmt->state = en_stmt_allocated;
554 }
555 break;
556
557 case en_stmt_cursoropen:
558 case en_stmt_fetched:
559 case en_stmt_xfetched:
560 if( pstmt->prep_state )
561 {
562 pstmt->state = en_stmt_prepared;
563 }
564 else
565 {
566 pstmt->state = en_stmt_allocated;
567 }
568 break;
569
570 case en_stmt_needdata:
571 case en_stmt_mustput:
572 case en_stmt_canput:
573 switch( pstmt->need_on )
574 {
575 case en_ExecDirect:
576 pstmt->state = en_stmt_allocated;
577 break;
578
579 case en_Execute:
580 pstmt->state = en_stmt_prepared;
581 break;
582
583 case en_SetPos:
584 pstmt->state = en_stmt_xfetched;
585 break;
586
587 default:
588 break;
589 }
590 pstmt->need_on = en_NullProc;
591 break;
592
593 default:
594 break;
595 }
596
597 return retcode;
598 }