]> git.saurik.com Git - wxWidgets.git/blob - src/iodbc/prepare.c
Guess what: ODBC updates and build fixes.
[wxWidgets.git] / src / iodbc / prepare.c
1 /** Prepare a query
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
31 RETCODE SQL_API SQLPrepare (
32 HSTMT hstmt,
33 UCHAR FAR* szSqlStr,
34 SDWORD cbSqlStr )
35 {
36 STMT_t FAR* pstmt = (STMT_t*)hstmt;
37
38 HPROC hproc = SQL_NULL_HPROC;
39 RETCODE retcode = SQL_SUCCESS;
40 int sqlstat = en_00000;
41
42 if( hstmt == SQL_NULL_HSTMT
43 || pstmt->hdbc == SQL_NULL_HDBC )
44 {
45 return SQL_INVALID_HANDLE;
46 }
47
48 /* check state */
49 if( pstmt->asyn_on == en_NullProc )
50 {
51 /* not on asyn state */
52 switch( pstmt->state )
53 {
54 case en_stmt_fetched:
55 case en_stmt_xfetched:
56 sqlstat = en_24000;
57 break;
58
59 case en_stmt_needdata:
60 case en_stmt_mustput:
61 case en_stmt_canput:
62 sqlstat = en_S1010;
63 break;
64
65 default:
66 break;
67 }
68 }
69 else if( pstmt->asyn_on != en_Prepare )
70 {
71 /* asyn on other */
72 sqlstat = en_S1010;
73 }
74
75 if( sqlstat != en_00000 )
76 {
77 PUSHSQLERR ( pstmt->herr, sqlstat );
78
79 return SQL_ERROR;
80 }
81
82 if( szSqlStr == NULL )
83 {
84 PUSHSQLERR ( pstmt->herr, en_S1009 );
85
86 return SQL_ERROR;
87 }
88
89 if( cbSqlStr < 0 && cbSqlStr != SQL_NTS )
90 {
91 PUSHSQLERR ( pstmt->herr, en_S1090 );
92
93 return SQL_ERROR;
94 }
95
96 hproc = _iodbcdm_getproc( pstmt->hdbc, en_Prepare );
97
98 if( hproc == SQL_NULL_HPROC )
99 {
100 PUSHSQLERR ( pstmt->herr, en_IM001 );
101 return SQL_ERROR;
102 }
103
104 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_Prepare, (
105 pstmt->dhstmt, szSqlStr, cbSqlStr) )
106
107 #if 0
108 retcode = hproc ( pstmt->dhstmt, szSqlStr, cbSqlStr );
109 #endif
110
111 /* stmt state transition */
112 if( pstmt->asyn_on == en_Prepare )
113 {
114 switch( retcode )
115 {
116 case SQL_SUCCESS:
117 case SQL_SUCCESS_WITH_INFO:
118 case SQL_ERROR:
119 pstmt->asyn_on = en_NullProc;
120 return retcode;
121
122 case SQL_STILL_EXECUTING:
123 default:
124 return retcode;
125 }
126 }
127
128 switch( retcode )
129 {
130 case SQL_STILL_EXECUTING:
131 pstmt->asyn_on = en_Prepare;
132 break;
133
134 case SQL_SUCCESS:
135 case SQL_SUCCESS_WITH_INFO:
136 pstmt->state = en_stmt_prepared;
137 pstmt->prep_state = 1;
138 break;
139
140 case SQL_ERROR:
141 switch( pstmt->state )
142 {
143 case en_stmt_prepared:
144 case en_stmt_executed:
145 pstmt->state = en_stmt_allocated;
146 pstmt->prep_state = 0;
147 break;
148
149 default:
150 break;
151 }
152
153 default:
154 break;
155 }
156
157 return retcode;
158 }
159
160 RETCODE SQL_API SQLSetCursorName (
161 HSTMT hstmt,
162 UCHAR FAR* szCursor,
163 SWORD cbCursor )
164 {
165 STMT_t FAR* pstmt = (STMT_t*)hstmt;
166 HPROC hproc = SQL_NULL_HPROC;
167
168 RETCODE retcode = SQL_SUCCESS;
169 int sqlstat = en_00000;
170
171 if( hstmt == SQL_NULL_HSTMT
172 || pstmt->hdbc == SQL_NULL_HDBC )
173 {
174 return SQL_INVALID_HANDLE;
175 }
176
177 if( szCursor == NULL )
178 {
179 PUSHSQLERR ( pstmt->herr, en_S1009 );
180
181 return SQL_ERROR;
182 }
183
184 if( cbCursor < 0 && cbCursor != SQL_NTS )
185 {
186 PUSHSQLERR ( pstmt->herr, en_S1090 );
187
188 return SQL_ERROR;
189 }
190
191 /* check state */
192 if( pstmt->asyn_on != en_NullProc )
193 {
194 sqlstat = en_S1010;
195 }
196 else
197 {
198 switch( pstmt->state )
199 {
200 case en_stmt_executed:
201 case en_stmt_cursoropen:
202 case en_stmt_fetched:
203 case en_stmt_xfetched:
204 sqlstat = en_24000;
205 break;
206
207 case en_stmt_needdata:
208 case en_stmt_mustput:
209 case en_stmt_canput:
210 sqlstat = en_S1010;
211 break;
212
213 default:
214 break;
215 }
216 }
217
218 if( sqlstat != en_00000 )
219 {
220 PUSHSQLERR ( pstmt->herr, sqlstat );
221
222 return SQL_ERROR;
223 }
224
225 hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetCursorName);
226
227 if( hproc == SQL_NULL_HPROC )
228 {
229 PUSHSQLERR ( pstmt->herr, en_IM001 );
230
231 return SQL_ERROR;
232 }
233
234 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetCursorName, (
235 pstmt->dhstmt, szCursor, cbCursor ) )
236
237 #if 0
238 retcode = hproc ( pstmt->dhstmt, szCursor, cbCursor );
239 #endif
240
241 if( retcode == SQL_SUCCESS
242 || retcode == SQL_SUCCESS_WITH_INFO )
243 {
244 pstmt->cursor_state = en_stmt_cursor_named;
245 }
246
247 return retcode;
248 }
249
250 RETCODE SQL_API SQLBindParameter (
251 HSTMT hstmt,
252 UWORD ipar,
253 SWORD fParamType,
254 SWORD fCType,
255 SWORD fSqlType,
256 UDWORD cbColDef,
257 SWORD ibScale,
258 PTR rgbValue,
259 SDWORD cbValueMax,
260 SDWORD FAR* pcbValue )
261 {
262 STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
263 HPROC hproc = SQL_NULL_HPROC;
264
265 int sqlstat = en_00000;
266 RETCODE retcode = SQL_SUCCESS;
267
268 if( hstmt == SQL_NULL_HSTMT
269 || pstmt->hdbc == SQL_NULL_HDBC )
270 {
271 return SQL_INVALID_HANDLE;
272 }
273
274 /* check param */
275 if( fSqlType > SQL_TYPE_MAX
276 || ( fSqlType < SQL_TYPE_MIN
277 && fSqlType > SQL_TYPE_DRIVER_START ) )
278 /* Note: SQL_TYPE_DRIVER_START is a nagtive number
279 * So, we use ">" */
280 {
281 sqlstat = en_S1004;
282 }
283 else if ( ipar < 1 )
284 {
285 sqlstat = en_S1093;
286 }
287 else if( (rgbValue == NULL && pcbValue == NULL)
288 && fParamType != SQL_PARAM_OUTPUT )
289 {
290 sqlstat = en_S1009;
291 /* This means, I allow output to nowhere
292 * (i.e. * junk output result). But I can't
293 * allow input from nowhere.
294 */
295 }
296 /**********
297 else if( cbValueMax < 0L && cbValueMax != SQL_SETPARAM_VALUE_MAX )
298 {
299 sqlstat = en_S1090;
300 }
301 **********/
302 else if( fParamType != SQL_PARAM_INPUT
303 && fParamType != SQL_PARAM_OUTPUT
304 && fParamType != SQL_PARAM_INPUT_OUTPUT )
305 {
306 sqlstat = en_S1105;
307 }
308 else
309 {
310 switch( fCType )
311 {
312 case SQL_C_DEFAULT:
313 case SQL_C_CHAR:
314 case SQL_C_BINARY:
315 case SQL_C_BIT:
316 case SQL_C_TINYINT:
317 case SQL_C_STINYINT:
318 case SQL_C_UTINYINT:
319 case SQL_C_SHORT:
320 case SQL_C_SSHORT:
321 case SQL_C_USHORT:
322 case SQL_C_LONG:
323 case SQL_C_SLONG:
324 case SQL_C_ULONG:
325 case SQL_C_FLOAT:
326 case SQL_C_DOUBLE:
327 case SQL_C_DATE:
328 case SQL_C_TIME:
329 case SQL_C_TIMESTAMP:
330 break;
331
332 default:
333 sqlstat = en_S1003;
334 break;
335 }
336 }
337
338 if(sqlstat != en_00000 )
339 {
340 PUSHSQLERR ( pstmt->herr, sqlstat );
341
342 return SQL_ERROR;
343 }
344
345 /* check state */
346 if( pstmt->state >= en_stmt_needdata
347 || pstmt->asyn_on != en_NullProc )
348 {
349 PUSHSQLERR ( pstmt->herr, en_S1010 );
350
351 retcode = SQL_ERROR;
352 }
353
354 hproc = _iodbcdm_getproc( pstmt->hdbc, en_BindParameter );
355
356 if( hproc == SQL_NULL_HPROC )
357 {
358 PUSHSQLERR ( pstmt->herr, en_IM001 );
359
360 return SQL_ERROR;
361 }
362
363 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_BindParameter, (
364 pstmt->dhstmt, ipar, fParamType, fCType, fSqlType,
365 cbColDef, ibScale, rgbValue, cbValueMax, pcbValue ) )
366
367 #if 0
368 retcode = hproc(pstmt->dhstmt, ipar, fParamType, fCType, fSqlType,
369 cbColDef, ibScale, rgbValue, cbValueMax, pcbValue );
370 #endif
371
372 return retcode;
373 }
374
375 RETCODE SQL_API SQLParamOptions(
376 HSTMT hstmt,
377 UDWORD crow,
378 UDWORD FAR* pirow )
379 {
380 STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
381 HPROC hproc;
382 RETCODE retcode;
383
384 if( hstmt == SQL_NULL_HSTMT
385 || pstmt->hdbc == SQL_NULL_HDBC )
386 {
387 return SQL_INVALID_HANDLE;
388 }
389
390 if( crow == (UDWORD)0UL )
391 {
392 PUSHSQLERR ( pstmt->herr, en_S1107 );
393
394 return SQL_ERROR;
395 }
396
397 if( pstmt->state >= en_stmt_needdata
398 || pstmt->asyn_on != en_NullProc )
399 {
400 PUSHSQLERR ( pstmt->herr, en_S1010 );
401
402 return SQL_ERROR;
403 }
404
405 hproc = _iodbcdm_getproc ( pstmt->hdbc, en_ParamOptions );
406
407 if( hproc == SQL_NULL_HPROC )
408 {
409 PUSHSQLERR ( pstmt->herr, en_IM001 );
410
411 return SQL_ERROR;
412 }
413
414 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_ParamOptions, (
415 pstmt->dhstmt, crow, pirow) )
416
417 #if 0
418 retcode = hproc ( pstmt->dhstmt, crow, pirow );
419 #endif
420
421 return retcode;
422 }
423
424 RETCODE SQL_API SQLSetScrollOptions(
425 HSTMT hstmt,
426 UWORD fConcurrency,
427 SDWORD crowKeyset,
428 UWORD crowRowset )
429 {
430 STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
431 HPROC hproc;
432 int sqlstat = en_00000;
433 RETCODE retcode;
434
435 if( hstmt == SQL_NULL_HSTMT
436 || pstmt->hdbc == SQL_NULL_HDBC )
437 {
438 return SQL_INVALID_HANDLE;
439 }
440
441 for(;;)
442 {
443 if( crowRowset == (UWORD)0 )
444 {
445 sqlstat = en_S1107;
446 break;
447 }
448
449 if( crowKeyset > (SDWORD)0L && crowKeyset < (SDWORD)crowRowset )
450 {
451 sqlstat = en_S1107;
452 break;
453 }
454
455 if( crowKeyset < 1 )
456 {
457 if( crowKeyset != SQL_SCROLL_FORWARD_ONLY
458 && crowKeyset != SQL_SCROLL_STATIC
459 && crowKeyset != SQL_SCROLL_KEYSET_DRIVEN
460 && crowKeyset != SQL_SCROLL_DYNAMIC )
461 {
462 sqlstat = en_S1107;
463 break;
464 }
465 }
466
467 if( fConcurrency != SQL_CONCUR_READ_ONLY
468 && fConcurrency != SQL_CONCUR_LOCK
469 && fConcurrency != SQL_CONCUR_ROWVER
470 && fConcurrency != SQL_CONCUR_VALUES )
471 {
472 sqlstat = en_S1108;
473 break;
474 }
475
476 if( pstmt->state != en_stmt_allocated )
477 {
478 sqlstat = en_S1010;
479 break;
480 }
481
482 hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetScrollOptions );
483
484 if( hproc == SQL_NULL_HPROC )
485 {
486 sqlstat = en_IM001;
487 break;
488 }
489
490 sqlstat = en_00000;
491 if( 1 ) /* turn off solaris warning message */
492 break;
493 }
494
495 if( sqlstat != en_00000 )
496 {
497 PUSHSQLERR ( pstmt->herr, sqlstat );
498
499 return SQL_ERROR;
500 }
501
502 CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetScrollOptions, (
503 pstmt->dhstmt,
504 fConcurrency,
505 crowKeyset,
506 crowRowset ) )
507
508 #if 0
509 retcode = hproc(pstmt->dhstmt,
510 fConcurrency,
511 crowKeyset,
512 crowRowset );
513 #endif
514
515 return retcode;
516 }
517
518 RETCODE SQL_API SQLSetParam (
519 HSTMT hstmt,
520 UWORD ipar,
521 SWORD fCType,
522 SWORD fSqlType,
523 UDWORD cbColDef,
524 SWORD ibScale,
525 PTR rgbValue,
526 SDWORD FAR *pcbValue)
527 {
528 return SQLBindParameter(hstmt,
529 ipar,
530 (SWORD)SQL_PARAM_INPUT_OUTPUT,
531 fCType,
532 fSqlType,
533 cbColDef,
534 ibScale,
535 rgbValue,
536 SQL_SETPARAM_VALUE_MAX,
537 pcbValue );
538 }