Files
wxWidgets/src/iodbc/fetch.c
Robert Roebling 1a6944fd74 added ODBC support
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@299 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1998-07-18 00:57:32 +00:00

676 lines
12 KiB
C

/** Fetch query result
Copyright (C) 1995 by Ke Jin <kejin@empress.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
**/
#include <../iodbc/iodbc.h>
#include <../iodbc/isql.h>
#include <../iodbc/isqlext.h>
#include <../iodbc/dlproc.h>
#include <../iodbc/herr.h>
#include <../iodbc/henv.h>
#include <../iodbc/hdbc.h>
#include <../iodbc/hstmt.h>
#include <../iodbc/itrace.h>
RETCODE SQL_API SQLFetch ( HSTMT hstmt )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_xfetched:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
default:
break;
}
}
else if( pstmt->asyn_on != en_Fetch )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_Fetch );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_Fetch, (pstmt->dhstmt) )
#if 0
retcode = hproc( pstmt->dhstmt );
#endif
/* state transition */
if( pstmt->asyn_on == en_Fetch )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_cursoropen:
case en_stmt_fetched:
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
pstmt->state = en_stmt_fetched;
pstmt->cursor_state = en_stmt_cursor_fetched;
break;
case SQL_NO_DATA_FOUND:
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
}
else
{
pstmt->state = en_stmt_allocated;
}
pstmt->cursor_state = en_stmt_cursor_no;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_Fetch;
break;
default:
break;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLExtendedFetch (
HSTMT hstmt,
UWORD fFetchType,
SDWORD irow,
UDWORD FAR* pcrow,
UWORD FAR* rgfRowStatus )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check fetch type */
if( fFetchType < SQL_FETCH_NEXT
|| fFetchType > SQL_FETCH_BOOKMARK )
{
/* Unlike MS driver manager(i.e. DM),
* we don't check driver's ODBC version
* against SQL_FETCH_RESUME (only 1.0)
* and SQL_FETCH_BOOKMARK (only 2.0).
*/
PUSHSQLERR ( pstmt->herr, en_S1106 );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_fetched:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
default:
break;
}
}
else if( pstmt->asyn_on != en_ExtendedFetch )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
hproc = _iodbcdm_getproc( pstmt->hdbc, en_ExtendedFetch );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_ExtendedFetch, (
pstmt->dhstmt,
fFetchType,
irow,
pcrow,
rgfRowStatus ) )
#if 0
retcode = hproc(pstmt->dhstmt,
fFetchType,
irow,
pcrow,
rgfRowStatus );
#endif
/* state transition */
if( pstmt->asyn_on == en_ExtendedFetch )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_cursoropen:
case en_stmt_xfetched:
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
pstmt->state = en_stmt_xfetched;
pstmt->cursor_state = en_stmt_cursor_xfetched;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_ExtendedFetch;
break;
default:
break;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLGetData(
HSTMT hstmt,
UWORD icol,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR* pcbValue )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument */
if( rgbValue == NULL )
{
sqlstat = en_S1009;
}
else if( cbValueMax < 0 )
{
sqlstat = en_S1090;
}
else
{
switch(fCType)
{
case SQL_C_DEFAULT:
case SQL_C_CHAR:
case SQL_C_BINARY:
case SQL_C_BIT:
case SQL_C_TINYINT:
case SQL_C_STINYINT:
case SQL_C_UTINYINT:
case SQL_C_SHORT:
case SQL_C_SSHORT:
case SQL_C_USHORT:
case SQL_C_LONG:
case SQL_C_SLONG:
case SQL_C_ULONG:
case SQL_C_FLOAT:
case SQL_C_DOUBLE:
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
break;
default:
sqlstat = en_S1003;
break;
}
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
sqlstat = en_S1010;
break;
case en_stmt_executed:
case en_stmt_cursoropen:
sqlstat = en_24000;
break;
default:
break;
}
}
else if( pstmt->asyn_on != en_GetData )
{
sqlstat = en_S1010;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_GetData );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_GetData, (
pstmt->dhstmt,
icol,
fCType,
rgbValue,
cbValueMax,
pcbValue ) )
#if 0
retcode = hproc(pstmt->dhstmt,
icol,
fCType,
rgbValue,
cbValueMax,
pcbValue );
#endif
/* state transition */
if( pstmt->asyn_on == en_GetData )
{
switch ( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_fetched:
case en_stmt_xfetched:
if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_GetData;
break;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLMoreResults( HSTMT hstmt )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
return SQL_NO_DATA_FOUND;
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
default:
break;
}
}
else if( pstmt->asyn_on != en_MoreResults )
{
PUSHSQLERR ( pstmt->herr, en_S1010 );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_MoreResults );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_MoreResults, (pstmt->dhstmt) )
#if 0
retcode = hproc( pstmt->dhstmt );
#endif
/* state transition */
if( pstmt->asyn_on == en_MoreResults )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NO_DATA_FOUND:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
/* driver should return SQL_NO_DATA_FOUND */
break;
case en_stmt_executed:
if( retcode == SQL_NO_DATA_FOUND )
{
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
}
else
{
pstmt->state = en_stmt_allocated;
}
}
else if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_MoreResults;
}
break;
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
if( retcode == SQL_SUCCESS )
{
break;
}
else if( retcode == SQL_NO_DATA_FOUND )
{
if( pstmt->prep_state )
{
pstmt->state = en_stmt_prepared;
}
else
{
pstmt->state = en_stmt_allocated;
}
}
else if( retcode == SQL_STILL_EXECUTING )
{
pstmt->asyn_on = en_MoreResults;
}
break;
default:
break;
}
return retcode;
}
RETCODE SQL_API SQLSetPos (
HSTMT hstmt,
UWORD irow,
UWORD fOption,
UWORD fLock )
{
STMT_t FAR* pstmt = (STMT_t FAR*)hstmt;
HPROC hproc;
RETCODE retcode;
int sqlstat = en_00000;
if( hstmt == SQL_NULL_HSTMT
|| pstmt->hdbc == SQL_NULL_HDBC )
{
return SQL_INVALID_HANDLE;
}
/* check argument value */
if( fOption > SQL_ADD
|| fLock > SQL_LOCK_UNLOCK )
{
PUSHSQLERR ( pstmt->herr, en_S1009 );
}
/* check state */
if( pstmt->asyn_on == en_NullProc )
{
switch( pstmt->state )
{
case en_stmt_allocated:
case en_stmt_prepared:
case en_stmt_fetched:
case en_stmt_needdata:
case en_stmt_mustput:
case en_stmt_canput:
sqlstat = en_S1010;
break;
case en_stmt_executed:
case en_stmt_cursoropen:
sqlstat = en_24000;
break;
default:
break;
}
}
else if( pstmt->asyn_on != en_SetPos )
{
sqlstat = en_S1010;
}
if( sqlstat != en_00000 )
{
PUSHSQLERR ( pstmt->herr, sqlstat );
return SQL_ERROR;
}
/* call driver */
hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetPos );
if( hproc == SQL_NULL_HPROC )
{
PUSHSQLERR ( pstmt->herr, en_IM001 );
return SQL_ERROR;
}
CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetPos, (
pstmt->dhstmt,
irow,
fOption,
fLock ) )
#if 0
retcode = hproc(pstmt->dhstmt,
irow,
fOption,
fLock );
#endif
/* state transition */
if( pstmt->asyn_on == en_SetPos )
{
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
case SQL_NEED_DATA:
case SQL_ERROR:
pstmt->asyn_on = en_NullProc;
break;
case SQL_STILL_EXECUTING:
default:
return retcode;
}
}
/* now, the only possible init state is 'xfetched' */
switch( retcode )
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
break;
case SQL_NEED_DATA:
pstmt->state = en_stmt_needdata;
pstmt->need_on = en_SetPos;
break;
case SQL_STILL_EXECUTING:
pstmt->asyn_on = en_SetPos;
break;
default:
break;
}
return retcode;
}