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