II_EXTERN II_VOID II_FAR II_EXPORT IIapi_getDescriptor( IIAPI_GETDESCRPARM II_FAR *getDescrParm ) { IIAPI_HNDL *handle; IIAPI_TRACE( IIAPI_TR_TRACE ) ( "IIapi_getDescriptor: retrieving columns from server\n" ); /* ** Validate Input parameters */ if ( ! getDescrParm ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_getDescriptor: null getDescriptor parameters\n" ); return; } getDescrParm->gd_genParm.gp_completed = FALSE; getDescrParm->gd_genParm.gp_status = IIAPI_ST_SUCCESS; getDescrParm->gd_genParm.gp_errorHandle = NULL; getDescrParm->gd_descriptorCount = 0; getDescrParm->gd_descriptor = NULL; handle = (IIAPI_HNDL *)getDescrParm->gd_stmtHandle; /* ** Make sure API is initialized */ if ( ! IIapi_initialized() ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_getDescriptor: API is not initialized\n" ); IIapi_appCallback( &getDescrParm->gd_genParm, NULL, IIAPI_ST_NOT_INITIALIZED ); return; } if ( ( ! IIapi_isStmtHndl( (IIAPI_STMTHNDL *)handle ) && ! IIapi_isDbevHndl( (IIAPI_DBEVHNDL *)handle ) ) || IIAPI_STALE_HANDLE( handle ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_getDescriptor: invalid handle\n" ); IIapi_appCallback( &getDescrParm->gd_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_getDescriptor: handle = %p\n", handle ); IIapi_clearAllErrors( handle ); IIapi_uiDispatch( IIAPI_EV_GETDESCR_FUNC, handle, (II_PTR)getDescrParm ); return; }
II_EXTERN II_VOID II_FAR II_EXPORT IIapi_getCopyMap( IIAPI_GETCOPYMAPPARM II_FAR *getCopyMapParm ) { IIAPI_STMTHNDL *stmtHndl; IIAPI_TRACE( IIAPI_TR_TRACE ) ( "IIapi_getCopyMap: retrieving copy information from server\n" ); /* ** Validate Input parameters */ if ( ! getCopyMapParm ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_getCopyMap: null getCopyMap parameters\n" ); return; } getCopyMapParm->gm_genParm.gp_completed = FALSE; getCopyMapParm->gm_genParm.gp_status = IIAPI_ST_SUCCESS; getCopyMapParm->gm_genParm.gp_errorHandle = NULL; stmtHndl = (IIAPI_STMTHNDL *)getCopyMapParm->gm_stmtHandle; /* ** Make sure API is initialized */ if ( ! IIapi_initialized() ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_getCopyMap: API is not initialized\n" ); IIapi_appCallback( &getCopyMapParm->gm_genParm, NULL, IIAPI_ST_NOT_INITIALIZED ); return; } if ( ! IIapi_isStmtHndl( stmtHndl ) || IIAPI_STALE_HANDLE( stmtHndl ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_getCopyMap: invalid statement handle\n" ); IIapi_appCallback( &getCopyMapParm->gm_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_getCopyMap: stmtHndl = %p\n", stmtHndl ); IIapi_clearAllErrors( (IIAPI_HNDL *)stmtHndl ); IIapi_uiDispatch( IIAPI_EV_GETCOPYMAP_FUNC, (IIAPI_HNDL *)stmtHndl, (II_PTR)getCopyMapParm ); return; }
II_EXTERN II_VOID II_FAR II_EXPORT IIapi_autocommit( IIAPI_AUTOPARM II_FAR *autoParm ) { IIAPI_TRANHNDL *tranHndl; IIAPI_CONNHNDL *connHndl; IIAPI_TRACE( IIAPI_TR_TRACE )("IIapi_autocommit: set autocommit state\n"); /* ** Validate Input parameters */ if ( ! autoParm ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_autocommit: null autocommit parameters\n" ); return; } autoParm->ac_genParm.gp_completed = FALSE; autoParm->ac_genParm.gp_status = IIAPI_ST_SUCCESS; autoParm->ac_genParm.gp_errorHandle = NULL; connHndl = (IIAPI_CONNHNDL *)autoParm->ac_connHandle; tranHndl = (IIAPI_TRANHNDL *)autoParm->ac_tranHandle; /* ** Make sure API is initialized */ if ( ! IIapi_initialized() ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_autocommit: API is not initialized\n" ); IIapi_appCallback( &autoParm->ac_genParm, NULL, IIAPI_ST_NOT_INITIALIZED ); return; } if ( ! connHndl && ! tranHndl ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_autocommit: no handle provided\n" ); IIapi_appCallback( &autoParm->ac_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } if ( connHndl && (! IIapi_isConnHndl( connHndl ) || IIAPI_STALE_HANDLE( connHndl )) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_autocommit: invalid connection handle\n" ); IIapi_appCallback( &autoParm->ac_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } if ( tranHndl && (! IIapi_isTranHndl( tranHndl ) || IIAPI_STALE_HANDLE( tranHndl )) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_autocommit: invalid transaction handle\n" ); IIapi_appCallback( &autoParm->ac_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_autocommit: connHndl = %p, tranHndl = %p\n", autoParm->ac_connHandle, autoParm->ac_tranHandle ); if ( connHndl ) IIapi_clearAllErrors( (IIAPI_HNDL *)connHndl ); if ( tranHndl ) IIapi_clearAllErrors( (IIAPI_HNDL *)tranHndl ); if ( ! tranHndl && ! IIapi_isQueEmpty( &connHndl->ch_tranHndlList ) ) { /* ** Application is attempting to enable autocommit mode ** with an active transaction. */ IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_autocommit: can't enable autocommit in a transaction\n" ); if ( ! IIapi_localError( (IIAPI_HNDL *)connHndl, E_AP0003_ACTIVE_TRANSACTIONS, II_SS25000_INV_XACT_STATE, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &autoParm->ac_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &autoParm->ac_genParm, (IIAPI_HNDL *)connHndl, IIAPI_ST_FAILURE ); return; } if ( tranHndl && ! IIapi_isQueEmpty( &tranHndl->th_stmtHndlList ) ) { /* ** Application is attempting to disable autocommit mode ** with active statements. */ IIAPI_TRACE( IIAPI_TR_ERROR ) ("IIapi_autocommit: can't disable autocommit with active statements\n"); if ( ! IIapi_localError( (IIAPI_HNDL *)tranHndl, E_AP0004_ACTIVE_QUERIES, II_SS25000_INV_XACT_STATE, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &autoParm->ac_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &autoParm->ac_genParm, (IIAPI_HNDL *)tranHndl, IIAPI_ST_FAILURE ); return; } if ( ! tranHndl ) { /* ** Enable autocommit mode. Create a transaction handle ** and return it to the application. */ if ( ! ( tranHndl = IIapi_createTranHndl( NULL, connHndl ) ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_autocommit: createTranHndl failed\n" ); IIapi_appCallback( &autoParm->ac_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); return; } autoParm->ac_tranHandle = (II_PTR)tranHndl; } else { /* ** Disable autocommit mode. The transaction handle ** will be deleted, so clear the output parameter. */ autoParm->ac_tranHandle = NULL; } IIapi_uiDispatch( IIAPI_EV_AUTO_FUNC, (IIAPI_HNDL *)tranHndl, (II_PTR)autoParm ); return; }
II_EXTERN II_VOID II_FAR II_EXPORT IIapi_scroll( IIAPI_SCROLLPARM II_FAR *scrollParm ) { IIAPI_STMTHNDL *stmtHndl; IIAPI_CONNHNDL *connHndl; bool valid; IIAPI_TRACE( IIAPI_TR_TRACE )( "IIapi_scroll: scroll cursor\n" ); /* ** Validate Input parameters */ if ( ! scrollParm ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_scroll: null scrollParms parameters\n" ); return; } scrollParm->sl_genParm.gp_completed = FALSE; scrollParm->sl_genParm.gp_status = IIAPI_ST_SUCCESS; scrollParm->sl_genParm.gp_errorHandle = NULL; stmtHndl = (IIAPI_STMTHNDL *)scrollParm->sl_stmtHandle; /* ** Make sure API is initialized */ if ( ! IIapi_initialized() ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_scroll: API is not initialized\n" ); IIapi_appCallback( &scrollParm->sl_genParm, NULL, IIAPI_ST_NOT_INITIALIZED ); return; } if ( ! IIapi_isStmtHndl( stmtHndl ) || IIAPI_STALE_HANDLE( stmtHndl ) || ! (connHndl = IIapi_getConnHndl( (IIAPI_HNDL *)stmtHndl)) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_scroll: invalid handle %p\n", stmtHndl ); IIapi_appCallback( &scrollParm->sl_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_scroll: handle = %p\n", stmtHndl ); IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_scroll: orientation = %d, offset = %d\n", scrollParm->sl_orientation, scrollParm->sl_offset ); IIapi_clearAllErrors( (IIAPI_HNDL *)stmtHndl ); /* ** Validate parameters. */ switch( scrollParm->sl_orientation ) { case IIAPI_SCROLL_NEXT : valid = TRUE; break; case IIAPI_SCROLL_BEFORE : case IIAPI_SCROLL_FIRST : case IIAPI_SCROLL_PRIOR : case IIAPI_SCROLL_CURRENT : case IIAPI_SCROLL_LAST : case IIAPI_SCROLL_AFTER : case IIAPI_SCROLL_ABSOLUTE : case IIAPI_SCROLL_RELATIVE : if ( connHndl->ch_partnerProtocol >= GCA_PROTOCOL_LEVEL_67 ) valid = TRUE; else { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_scroll: scrolling not supported\n" ); valid = FALSE; } break; default : IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_scroll: invalid orientation: %d\n", (II_LONG)scrollParm->sl_orientation ); valid = FALSE; break; } if ( ! valid ) { if ( ! IIapi_localError( (IIAPI_HNDL *)stmtHndl, E_AP0011_INVALID_PARAM_VALUE, II_SS22003_NUM_VAL_OUT_OF_RANGE, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &scrollParm->sl_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &scrollParm->sl_genParm, (IIAPI_HNDL *)stmtHndl, IIAPI_ST_FAILURE ); return; } IIapi_uiDispatch( IIAPI_EV_SCROLL_FUNC, (IIAPI_HNDL *)stmtHndl, (II_PTR)scrollParm ); return; }
II_EXTERN II_VOID II_FAR II_EXPORT IIapi_position( IIAPI_POSPARM II_FAR *posParm ) { IIAPI_STMTHNDL *stmtHndl; IIAPI_CONNHNDL *connHndl; bool valid; IIAPI_TRACE( IIAPI_TR_TRACE )( "IIapi_position: position cursor\n" ); /* ** Validate Input parameters */ if ( ! posParm ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_position: null posParms parameters\n" ); return; } posParm->po_genParm.gp_completed = FALSE; posParm->po_genParm.gp_status = IIAPI_ST_SUCCESS; posParm->po_genParm.gp_errorHandle = NULL; stmtHndl = (IIAPI_STMTHNDL *)posParm->po_stmtHandle; /* ** Make sure API is initialized */ if ( ! IIapi_initialized() ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_position: API is not initialized\n" ); IIapi_appCallback( &posParm->po_genParm, NULL, IIAPI_ST_NOT_INITIALIZED ); return; } if ( ! IIapi_isStmtHndl( stmtHndl ) || IIAPI_STALE_HANDLE( stmtHndl ) || ! (connHndl = IIapi_getConnHndl( (IIAPI_HNDL *)stmtHndl )) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_position: invalid handle %p\n", stmtHndl ); IIapi_appCallback( &posParm->po_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_position: handle = %p\n", stmtHndl ); IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_position: reference = %d, offset = %d, rows = %d\n", posParm->po_reference, posParm->po_offset, posParm->po_rowCount ); IIapi_clearAllErrors( (IIAPI_HNDL *)stmtHndl ); /* ** Validate parameters. */ switch( posParm->po_reference ) { case IIAPI_POS_BEGIN : case IIAPI_POS_END : if ( connHndl->ch_partnerProtocol >= GCA_PROTOCOL_LEVEL_67 ) valid = TRUE; else { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_scroll: scrolling not supported\n" ); valid = FALSE; } break; case IIAPI_POS_CURRENT : if ( connHndl->ch_partnerProtocol >= GCA_PROTOCOL_LEVEL_67 || posParm->po_offset == 1 ) valid = TRUE; else { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_scroll: scrolling not supported\n" ); valid = FALSE; } break; default : IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_position: invalid reference: %d\n", (II_LONG)posParm->po_reference ); valid = FALSE; break; } if ( posParm->po_rowCount < ((connHndl->ch_partnerProtocol >= GCA_PROTOCOL_LEVEL_67) ? 0 : 1) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_position: invalid row count: %d\n", (II_LONG)posParm->po_rowCount ); valid = FALSE; } if ( ! valid ) { if ( ! IIapi_localError( (IIAPI_HNDL *)stmtHndl, E_AP0011_INVALID_PARAM_VALUE, II_SS22003_NUM_VAL_OUT_OF_RANGE, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &posParm->po_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &posParm->po_genParm, (IIAPI_HNDL *)stmtHndl, IIAPI_ST_FAILURE); return; } IIapi_uiDispatch( IIAPI_EV_POSITION_FUNC, (IIAPI_HNDL *) stmtHndl, (II_PTR)posParm ); return; }
static II_BOOL sm_execute ( IIAPI_ACTION action, IIAPI_HNDL *ev_hndl, IIAPI_HNDL *sm_hndl, II_PTR parmBlock ) { IIAPI_TRANHNDL *tranHndl = (IIAPI_TRANHNDL *)sm_hndl; IIAPI_MSG_BUFF *msgBuff; IIAPI_STATUS status; II_BOOL success = TRUE; char queryText[ 64 ]; switch( action ) { case SQL_TA_REMC : /* ** Remember callback. */ tranHndl->th_callback = TRUE; tranHndl->th_parm = (IIAPI_GENPARM *)parmBlock; break; case SQL_TA_RECV : { /* ** Issue receive message request. */ IIAPI_MSG_BUFF *msgBuff = IIapi_allocMsgBuffer( sm_hndl ); if ( ! msgBuff ) status = IIAPI_ST_OUT_OF_MEMORY; else status = IIapi_rcvNormalGCA( sm_hndl, msgBuff, (II_LONG)(-1) ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; } case SQL_TA_SCOM : /* ** Format and send GCA_COMMIT message. */ if ( ! (msgBuff = IIapi_allocMsgBuffer( sm_hndl )) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } msgBuff->msgType = GCA_COMMIT; msgBuff->flags = IIAPI_MSG_EOD; status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; case SQL_TA_SRB : /* ** Format and send GCA_ROLLBACK message. */ if ( ! (msgBuff = IIapi_allocMsgBuffer( sm_hndl )) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } msgBuff->msgType = GCA_ROLLBACK; msgBuff->flags = IIAPI_MSG_EOD; status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; case SQL_TA_SSP : { /* ** Create savepoint handle. Format and ** send GCA_QUERY message 'savepoint <sp>'. */ IIAPI_SAVEPTHNDL *savePtHndl; IIAPI_SAVEPTPARM *savePtParm = (IIAPI_SAVEPTPARM *)parmBlock; if ( ! IIapi_createSavePtHndl( savePtParm ) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } savePtHndl = savePtParm->sp_savePointHandle; STprintf( queryText, "savepoint %s\n", savePtHndl->sp_savePtName ); if ( ! (msgBuff = IIapi_createMsgQuery( sm_hndl, queryText )) ) { IIapi_deleteSavePtHndl( savePtHndl ); savePtParm->sp_savePointHandle = NULL; status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) { IIapi_deleteSavePtHndl( savePtHndl ); savePtParm->sp_savePointHandle = NULL; success = FALSE; } break; } case SQL_TA_SRBS : { /* ** Format and send GCA_QUERY message 'rollback to <savepoint>'. */ IIAPI_ROLLBACKPARM *rollParm = (IIAPI_ROLLBACKPARM *)parmBlock; IIAPI_SAVEPTHNDL *savePtHndl = rollParm->rb_savePointHandle; STprintf(queryText, "rollback to %s\n", savePtHndl->sp_savePtName); if ( ! (msgBuff = IIapi_createMsgQuery( sm_hndl, queryText )) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; } case SQL_TA_SAON : /* ** Format and send GCA_QUERY message 'set autocommit on'. */ if ( ! (msgBuff = IIapi_createMsgQuery( sm_hndl, "set autocommit on" )) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; case SQL_TA_SAOF : /* ** Format and send GCA_QUERY message 'set autocommit off'. */ if ( ! (msgBuff = IIapi_createMsgQuery( sm_hndl, "set autocommit off" )) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; case SQL_TA_SSEC : /* ** Format and send GCA_SECURE message. */ if ( ! ( msgBuff = IIapi_createMsgSecure( tranHndl ) ) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; case SQL_TA_SXAS : { /* ** Send XA Start message. */ IIAPI_XASTARTPARM *startParm = (IIAPI_XASTARTPARM *)parmBlock; if ( ! (msgBuff = IIapi_createMsgXA( sm_hndl, GCA_XA_START, &startParm->xs_tranID.ti_value.xaXID, startParm->xs_flags )) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; } case SQL_TA_SXAE : { /* ** Send XA End message. */ IIAPI_XAENDPARM *endParm = (IIAPI_XAENDPARM *)parmBlock; if ( ! (msgBuff = IIapi_createMsgXA( sm_hndl, GCA_XA_END, &endParm->xe_tranID.ti_value.xaXID, endParm->xe_flags )) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } status = IIapi_sndGCA( sm_hndl, msgBuff, NULL ); if ( status != IIAPI_ST_SUCCESS ) success = FALSE; break; } case SQL_TA_PEND : /* ** Return transaction aborted to all pending operations. */ { IIAPI_STMTHNDL *stmtHndl; for( stmtHndl = (IIAPI_STMTHNDL *)tranHndl-> th_stmtHndlList.q_next; stmtHndl != (IIAPI_STMTHNDL *)&tranHndl->th_stmtHndlList; stmtHndl = (IIAPI_STMTHNDL *)stmtHndl-> sh_header.hd_id.hi_queue.q_next ) IIapi_abortStmtHndl( stmtHndl, E_AP0002_TRANSACTION_ABORTED, II_SS40001_SERIALIZATION_FAIL, IIAPI_ST_FAILURE ); } break; case SQL_TA_DELH : /* ** Mark handle for deletion. */ QUremove( (QUEUE *)tranHndl ); sm_hndl->hd_delete = TRUE; /* ** If this was a distributed transaction, ** the associated distributed transaction ** name should be releasable during the ** callback. Since the transaction handle ** has not actually been deleted, it is ** still associated with the distributed ** transaction name. Normally, cases such ** as this are serialized by the dispatch ** operations queue, but IIapi_releaseXID() ** is not a dispatched request. So we need ** to drop the association prior to making ** the callback. */ if ( tranHndl->th_tranName ) { QUremove( &tranHndl->th_tranNameQue ); tranHndl->th_tranName = NULL; } break; case SQL_TA_DELX : /* ** Free associated transaction name handle. */ if ( tranHndl->th_tranName ) /* Should never be NULL */ { QUremove( &tranHndl->th_tranNameQue ); IIapi_deleteTranName( tranHndl->th_tranName ); tranHndl->th_tranName = NULL; } /* ** Mark handle for deletion. */ QUremove( (QUEUE *)tranHndl ); sm_hndl->hd_delete = TRUE; break; case SQL_TA_ERAB : /* ** Transaction Aborted. */ IIAPI_TRACE( IIAPI_TR_ERROR ) ( "%s: Transaction aborted\n", sql_tran_sm.sm_id ); if ( ! IIapi_localError( sm_hndl, E_AP0002_TRANSACTION_ABORTED, II_SS40001_SERIALIZATION_FAIL, IIAPI_ST_FAILURE ) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; } break; case SQL_TA_ERCF : /* ** Commit failed. */ IIAPI_TRACE( IIAPI_TR_ERROR ) ( "%s: transaction commit failed\n", sql_tran_sm.sm_id ); if ( ! IIapi_localError( sm_hndl, E_AP000B_COMMIT_FAILED, II_SS40001_SERIALIZATION_FAIL, IIAPI_ST_FAILURE ) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; } break; case SQL_TA_ERPC : /* ** Prepare-to-commit failed. */ IIAPI_TRACE( IIAPI_TR_ERROR ) ( "%s: transaction prepare failed\n", sql_tran_sm.sm_id ); if ( ! IIapi_localError( sm_hndl, E_AP000C_2PC_REFUSED, II_SS40001_SERIALIZATION_FAIL, IIAPI_ST_FAILURE ) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; } break; case SQL_TA_RRSP : { /* ** Read response message. */ IIAPI_MSG_BUFF *msgBuff = (IIAPI_MSG_BUFF *)parmBlock; GCA_RE_DATA respData; if ( (status = IIapi_readMsgResponse( msgBuff, &respData, TRUE )) != IIAPI_ST_SUCCESS ) { success = FALSE; break; } /* ** Check for XA error */ if ( respData.gca_rqstatus & GCA_XA_ERROR_MASK && respData.gca_errd5 && ! IIapi_xaError( sm_hndl, respData.gca_errd5 ) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } break; } case SQL_TA_RXAR : { /* ** Read XA response message. */ IIAPI_MSG_BUFF *msgBuff = (IIAPI_MSG_BUFF *)parmBlock; GCA_RE_DATA respData; if ( (status = IIapi_readMsgResponse( msgBuff, &respData, TRUE )) != IIAPI_ST_SUCCESS ) { success = FALSE; break; } /* ** If no XA error is returned, generate generic XA error. */ if ( ! (respData.gca_rqstatus & GCA_XA_ERROR_MASK) || ! respData.gca_errd5 ) respData.gca_errd5 = IIAPI_XAER_RMERR; if ( ! IIapi_xaError( sm_hndl, respData.gca_errd5 ) ) { status = IIAPI_ST_OUT_OF_MEMORY; success = FALSE; break; } break; } case SQL_TA_CBOK : /* ** Callback with success. Note that ** this will pick up the most severe ** status from the errors associated ** with the event handle. */ if ( tranHndl->th_callback ) { IIapi_appCallback(tranHndl->th_parm, sm_hndl, IIAPI_ST_SUCCESS); tranHndl->th_callback = FALSE; } break; case SQL_TA_CBFL : /* ** Callback with failure. */ if ( tranHndl->th_callback ) { IIapi_appCallback(tranHndl->th_parm, sm_hndl, IIAPI_ST_FAILURE); tranHndl->th_callback = FALSE; } break; case SQL_TA_CBIF : /* ** API function called in wrong state. */ if ( ! IIapi_localError( sm_hndl, E_AP0006_INVALID_SEQUENCE, II_SS5000R_RUN_TIME_LOGICAL_ERROR, IIAPI_ST_FAILURE ) ) status = IIAPI_ST_OUT_OF_MEMORY; else status = IIAPI_ST_FAILURE; /* ** This may not have been a transaction ** related function, and we may have a ** callback saved on the transaction ** handle, so we carefully make the ** callback to the caller making sure ** not to disturb the transaction handle. */ IIapi_appCallback( (IIAPI_GENPARM *)parmBlock, sm_hndl, status ); break; case SQL_TA_CBAB : /* ** Callback with transaction abort. */ if ( tranHndl->th_callback ) { if ( ! IIapi_localError( sm_hndl, E_AP0002_TRANSACTION_ABORTED, II_SS40001_SERIALIZATION_FAIL, IIAPI_ST_FAILURE ) ) status = IIAPI_ST_OUT_OF_MEMORY; else status = IIAPI_ST_FAILURE; IIapi_appCallback( tranHndl->th_parm, sm_hndl, status ); tranHndl->th_callback = FALSE; } break; case SQL_TA_CBABX : /* ** Callback with XA transaction abort. */ if ( tranHndl->th_callback ) { if ( ! IIapi_xaError( sm_hndl, IIAPI_XA_RBROLLBACK ) ) status = IIAPI_ST_OUT_OF_MEMORY; else status = IIAPI_ST_FAILURE; IIapi_appCallback( tranHndl->th_parm, sm_hndl, status ); tranHndl->th_callback = FALSE; } break; case SQL_TA_RCVE : /* ** Receive error. ** ** We have received an invalid message. ** Since the connection state machine ** may ignore this particular message ** type, convert to a type which will ** ensure the proper handling in all ** state machines. */ IIapi_liDispatch( IIAPI_EV_UNEXPECTED_RCVD, sm_hndl, NULL, NULL ); break; case SQL_TA_HALT : /* ** Halt state machine execution. */ return( FALSE ); } /* ** If we couldn't complete the action, callback with failure. */ if ( ! success && tranHndl->th_callback ) { IIapi_appCallback( tranHndl->th_parm, sm_hndl, status ); tranHndl->th_callback = FALSE; } return( success ); }
static II_BOOL sm_execute ( IIAPI_ACTION action, IIAPI_HNDL *ev_hndl, IIAPI_HNDL *sm_hndl, II_PTR parmBlock ) { IIAPI_TRANHNDL *tranHndl = (IIAPI_TRANHNDL *)sm_hndl; IIAPI_SAVEPTHNDL *savePtHndl; IIAPI_SAVEPTPARM *savePtParm; IIAPI_STATUS status = OK; II_BOOL success = TRUE; char queryText[ 64 ]; switch( action ) { case NS_TA_REMC : /* ** Remember callback. */ tranHndl->th_callback = TRUE; tranHndl->th_parm = (IIAPI_GENPARM *)parmBlock; break; case NS_TA_DELH : /* ** Mark handle for deletion. */ QUremove( (QUEUE *)tranHndl ); sm_hndl->hd_delete = TRUE; break; case NS_TA_CBOK : /* ** Callback with success. Note that ** this will pick up the most severe ** status from the errors associated ** with the event handle. */ if ( tranHndl->th_callback ) { IIapi_appCallback(tranHndl->th_parm, sm_hndl, IIAPI_ST_SUCCESS); tranHndl->th_callback = FALSE; } break; case NS_TA_CBIF : /* ** API function called in wrong state. */ if ( ! IIapi_localError( sm_hndl, E_AP0006_INVALID_SEQUENCE, II_SS5000R_RUN_TIME_LOGICAL_ERROR, IIAPI_ST_FAILURE ) ) status = IIAPI_ST_OUT_OF_MEMORY; else status = IIAPI_ST_FAILURE; /* ** This may not have been a transaction ** related function, and we may have a ** callback saved on the transaction ** handle, so we carefully make the ** callback to the caller making sure ** not to disturb the transaction handle. */ IIapi_appCallback( (IIAPI_GENPARM *)parmBlock, sm_hndl, status ); /* ** We must return the failure here rather ** than following the normal exit route ** to ensure that the transaction handle ** callback does not get made. */ return( FALSE ); case NS_TA_RCVE : /* ** Receive error. ** ** We have received an invalid message. ** Since the connection state machine ** may ignore this particular message ** type, convert to a type which will ** ensure the proper handling in all ** state machines. */ IIapi_liDispatch( IIAPI_EV_UNEXPECTED_RCVD, sm_hndl, NULL, NULL ); return( FALSE ); } /* ** If we couldn't complete the action, callback with failure. */ if ( ! success && tranHndl->th_callback ) { IIapi_appCallback( tranHndl->th_parm, sm_hndl, status ); tranHndl->th_callback = FALSE; } return( success ); }
II_EXTERN II_VOID II_FAR II_EXPORT IIapi_batch( IIAPI_BATCHPARM II_FAR *batchParm ) { IIAPI_CONNHNDL *connHndl; IIAPI_TRANHNDL *tranHndl; IIAPI_STMTHNDL *stmtHndl; IIAPI_HNDL *handle; IIAPI_TRACE( IIAPI_TR_TRACE )( "IIapi_batch: adding a batch query\n" ); /* ** Validate Input parameters */ if ( ! batchParm ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: null batch parameters\n" ); return; } batchParm->ba_genParm.gp_completed = FALSE; batchParm->ba_genParm.gp_status = IIAPI_ST_SUCCESS; batchParm->ba_genParm.gp_errorHandle = NULL; connHndl = (IIAPI_CONNHNDL *)batchParm->ba_connHandle; handle = (IIAPI_HNDL *)batchParm->ba_tranHandle; stmtHndl = (IIAPI_STMTHNDL *)batchParm->ba_stmtHandle; /* ** Make sure API is initialized */ if ( ! IIapi_initialized() ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: API is not initialized\n" ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_NOT_INITIALIZED ); return; } /* ** Validate connection handle. */ if ( ! IIapi_isConnHndl( connHndl ) || IIAPI_STALE_HANDLE( connHndl ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: invalid connHndl %p\n", connHndl ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } /* ** Validate transaction handle. */ if ( handle && ! IIapi_isTranName( (IIAPI_TRANNAME *)handle ) && (! IIapi_isTranHndl( (IIAPI_TRANHNDL *)handle ) || IIAPI_STALE_HANDLE( handle )) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: invalid tranHndl %p\n", handle ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } /* ** Validate statement handle. */ if ( stmtHndl ) { if ( ! IIapi_isStmtHndl( (IIAPI_STMTHNDL *)stmtHndl ) || IIAPI_STALE_HANDLE( stmtHndl ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: invalid stmtHndl %p\n", stmtHndl ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } if ( ! handle || IIapi_isTranName( (IIAPI_TRANNAME *)handle) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: transaction handle required\n" ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } if ( handle != (IIAPI_HNDL *)stmtHndl->sh_tranHndl ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: wrong tranHndl %p for stmtHndl %p\n", handle, stmtHndl ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } if ( connHndl != IIapi_getConnHndl( (IIAPI_HNDL *)stmtHndl ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: wrong connHndl %p for stmtHndl %p\n", connHndl, stmtHndl ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } } IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_batch: connHndl = %p, tranHndl = %p, stmtHndl = %p, queryType = %d\n", batchParm->ba_connHandle, batchParm->ba_tranHandle, batchParm->ba_stmtHandle, batchParm->ba_queryType ); IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_batch: queryText = %s\n", batchParm->ba_queryText ? batchParm->ba_queryText : "<NULL>" ); IIapi_clearAllErrors( stmtHndl ? (IIAPI_HNDL *)stmtHndl : ( (handle && IIapi_isTranHndl( (IIAPI_TRANHNDL *)handle )) ? handle : (IIAPI_HNDL *)connHndl ) ); /* ** Check that batch processing is supported on the connection. */ if ( connHndl->ch_partnerProtocol < GCA_PROTOCOL_LEVEL_68 ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: batch not supported at protocol level %d\n", connHndl->ch_partnerProtocol ); if ( ! IIapi_localError( (IIAPI_HNDL *)connHndl, E_AP001F_BATCH_UNSUPPORTED, II_SS50008_UNSUPPORTED_STMT, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &batchParm->ba_genParm, (IIAPI_HNDL *)connHndl, IIAPI_ST_FAILURE ); return; } /* ** Check restrictions on query type and associated info. */ if ( connHndl->ch_type != IIAPI_SMT_SQL || (batchParm->ba_queryType != IIAPI_QT_QUERY && batchParm->ba_queryType != IIAPI_QT_EXEC && batchParm->ba_queryType != IIAPI_QT_EXEC_PROCEDURE) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: invalid query type %d for connection type %d\n", batchParm->ba_queryType, connHndl->ch_type ); if ( ! IIapi_localError( (IIAPI_HNDL *)connHndl, E_AP0011_INVALID_PARAM_VALUE, II_SS50008_UNSUPPORTED_STMT, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &batchParm->ba_genParm, (IIAPI_HNDL *)connHndl, IIAPI_ST_FAILURE ); return; } if ( batchParm->ba_queryType != IIAPI_QT_EXEC_PROCEDURE && ! batchParm->ba_queryText ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: query requires query text\n" ); if ( ! IIapi_localError( (IIAPI_HNDL *)connHndl, E_AP0011_INVALID_PARAM_VALUE, II_SS5000R_RUN_TIME_LOGICAL_ERROR, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &batchParm->ba_genParm, (IIAPI_HNDL *)connHndl, IIAPI_ST_FAILURE ); return; } if ( batchParm->ba_queryType == IIAPI_QT_EXEC_PROCEDURE && ! batchParm->ba_parameters ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: query requires parameters, none indicated\n" ); if ( ! IIapi_localError( (IIAPI_HNDL *)connHndl, E_AP0011_INVALID_PARAM_VALUE, II_SS5000R_RUN_TIME_LOGICAL_ERROR, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &batchParm->ba_genParm, (IIAPI_HNDL *)connHndl, IIAPI_ST_FAILURE ); return; } /* ** Allocate a transaction handle if one was not provided. */ if ( ! handle || IIapi_isTranName( (IIAPI_TRANNAME *)handle ) ) { /* ** Check to see if there is an active transaction. */ if ( ! IIapi_isQueEmpty( (QUEUE *)&connHndl->ch_tranHndlList ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ("IIapi_batch: connection has active transaction.\n"); if ( ! IIapi_localError( (IIAPI_HNDL *)connHndl, E_AP0003_ACTIVE_TRANSACTIONS, II_SS25000_INV_XACT_STATE, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &batchParm->ba_genParm, (IIAPI_HNDL *)connHndl, IIAPI_ST_FAILURE ); return; } if ( ! ( tranHndl = IIapi_createTranHndl( (IIAPI_TRANNAME *)batchParm->ba_tranHandle, (IIAPI_CONNHNDL *)batchParm->ba_connHandle ) ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: createTranHndl failed\n" ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); return; } } else { /* ** Use existing transaction handle. */ tranHndl = (IIAPI_TRANHNDL *)handle; IIapi_clearAllErrors( (IIAPI_HNDL *)tranHndl ); } /* ** Allocate a new statement handle or initialize existing handle. */ if ( stmtHndl ) initStmtHndl( stmtHndl ); else if ( ! (stmtHndl = IIapi_createStmtHndl( connHndl, tranHndl )) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_batch: createStmtHndl failed\n" ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); goto freeTranHandle; } /* ** Update statement handle with batch query information. */ if ( batchParm->ba_queryText && ! (stmtHndl->sh_queryText = STalloc( batchParm->ba_queryText )) ) { IIAPI_TRACE( IIAPI_TR_FATAL ) ( "IIapi_batch: can't alloc query text\n" ); IIapi_appCallback( &batchParm->ba_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); goto freeStmtHandle; } stmtHndl->sh_queryType = batchParm->ba_queryType; if ( batchParm->ba_parameters ) stmtHndl->sh_flags |= IIAPI_SH_PARAMETERS; /* ** The current set of external batch/query flags ** are not applicable to batch processing, but ** we pass them along anyway. */ stmtHndl->sh_flags |= batchParm->ba_flags & IIAPI_QF_ALL_FLAGS; batchParm->ba_stmtHandle = (II_PTR)stmtHndl; batchParm->ba_tranHandle = (II_PTR)tranHndl; IIapi_uiDispatch( IIAPI_EV_BATCH_FUNC, (IIAPI_HNDL *)stmtHndl, (II_PTR)batchParm ); return; freeStmtHandle: /* ** If the statement handle is not the input handle, ** then we allocated a new handle above and we must ** now delete it. */ if ( stmtHndl != (IIAPI_STMTHNDL *)batchParm->ba_stmtHandle ) IIapi_deleteStmtHndl( stmtHndl ); freeTranHandle: /* ** If the transaction handle is not the input handle, ** then we allocated a new handle above and we must ** now delete it. */ if ( tranHndl != (IIAPI_TRANHNDL *)batchParm->ba_tranHandle ) IIapi_deleteTranHndl( tranHndl ); return; }
II_EXTERN II_VOID II_FAR II_EXPORT IIapi_putColumns( IIAPI_PUTCOLPARM II_FAR *putColParm ) { IIAPI_STMTHNDL *stmtHndl; II_ULONG err_code; IIAPI_TRACE( IIAPI_TR_TRACE ) ( "IIapi_putColumns: sending tuple to server\n" ); /* ** Validate Input parameters */ if ( ! putColParm ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_putColumns: null putColumns parameters\n" ); return; } putColParm->pc_genParm.gp_completed = FALSE; putColParm->pc_genParm.gp_status = IIAPI_ST_SUCCESS; putColParm->pc_genParm.gp_errorHandle = NULL; stmtHndl = (IIAPI_STMTHNDL *)putColParm->pc_stmtHandle; /* ** Make sure API is initialized */ if ( ! IIapi_initialized() ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_putColumns: API is not initialized\n" ); IIapi_appCallback( &putColParm->pc_genParm, NULL, IIAPI_ST_NOT_INITIALIZED ); return; } if ( ! IIapi_isStmtHndl( stmtHndl ) || IIAPI_STALE_HANDLE( stmtHndl ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_putColumns: invalid statement handle\n" ); IIapi_appCallback( &putColParm->pc_genParm, NULL, IIAPI_ST_INVALID_HANDLE ); return; } IIAPI_TRACE( IIAPI_TR_INFO ) ( "IIapi_putColumns: stmtHndl = %p\n", stmtHndl ); IIapi_clearAllErrors( (IIAPI_HNDL *)stmtHndl ); if ( ! IIapi_validPColCount( stmtHndl, putColParm ) ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ("IIapi_putColumns: invalid count: %d (actual %d, index %d)\n", (II_LONG)putColParm->pc_columnCount, (II_LONG)stmtHndl->sh_colCount, (II_LONG)stmtHndl->sh_colIndex ); if ( ! IIapi_localError( (IIAPI_HNDL *)stmtHndl, E_AP0010_INVALID_COLUMN_COUNT, II_SS21000_CARD_VIOLATION, IIAPI_ST_FAILURE ) ) IIapi_appCallback( &putColParm->pc_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); else IIapi_appCallback( &putColParm->pc_genParm, (IIAPI_HNDL *)stmtHndl, IIAPI_ST_FAILURE ); return; } if ( (err_code = IIapi_validDataValue( putColParm->pc_columnCount, &stmtHndl->sh_colDescriptor[ stmtHndl->sh_colIndex ], putColParm->pc_columnData )) != OK ) { IIAPI_TRACE( IIAPI_TR_ERROR ) ( "IIapi_putColumns: column data conflicts with descriptor\n" ); /* ** We only issue a warning on data conflicts, but if the ** warning can't be generated then abort the operation. */ if ( ! IIapi_localError( (IIAPI_HNDL *)stmtHndl, err_code, II_SS22500_INVALID_DATA_TYPE, IIAPI_ST_WARNING ) ) { IIapi_appCallback( &putColParm->pc_genParm, NULL, IIAPI_ST_OUT_OF_MEMORY ); return; } } stmtHndl->sh_colFetch = putColParm->pc_columnCount; IIapi_uiDispatch( IIAPI_EV_PUTCOLUMN_FUNC, (IIAPI_HNDL *)stmtHndl, (II_PTR)putColParm ); return; }