git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@299 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
676 lines
12 KiB
C
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;
|
|
}
|