void gcd_msg_cursor( GCD_CCB *ccb ) { DAM_ML_CUR cursor; STMT_ID stmt_id; GCD_SCB *scb; GCD_PCB *pcb; STATUS status; u_i2 pos_anchor = MSG_POS_CURRENT; /* Default to NEXT */ i4 pos_offset = 1; u_i4 pre_fetch = 1; bool incomplete = FALSE; bool got_id = FALSE; if ( ! gcd_get_i2( ccb, (u_i1 *)&cursor.cursor_op ) ) { if ( GCD_global.gcd_trace_level >= 1 ) TRdisplay( "%4d GCD no cursor op specified\n", ccb->id ); gcd_sess_abort( ccb, E_GC480A_PROTOCOL_ERROR ); return; } if ( GCD_global.gcd_trace_level >= 3 ) TRdisplay( "%4d GCD Cursor operation: %s\n", ccb->id, gcu_lookup( curMap, cursor.cursor_op ) ); if ( ! (pcb = gcd_new_pcb( ccb )) || ! (pcb->rcb = gcd_new_rcb( ccb, -1 )) ) { if ( pcb ) gcd_del_pcb( pcb ); gcd_sess_abort( ccb, E_GC4808_NO_MEMORY ); return; } while( ccb->msg.msg_len ) { DAM_ML_PM cp; u_i1 u_i1_val; u_i2 u_i2_val; u_i4 u_i4_val; incomplete = TRUE; if ( ! gcd_get_i2( ccb, (u_i1 *)&cp.param_id ) ) break; if ( ! gcd_get_i2( ccb, (u_i1 *)&cp.val_len ) ) break; switch( cp.param_id ) { case MSG_CUR_STMT_ID : if ( cp.val_len != (CV_N_I4_SZ * 2) || ! gcd_get_i4( ccb, (u_i1 *)&stmt_id.id_high ) || ! gcd_get_i4( ccb, (u_i1 *)&stmt_id.id_low ) ) break; incomplete = FALSE; got_id = TRUE; break; case MSG_CUR_PRE_FETCH : switch( cp.val_len ) { case 1 : if ( gcd_get_i1( ccb, (u_i1 *)&u_i1_val ) ) { pre_fetch = max( pre_fetch, u_i1_val ); incomplete = FALSE; } break; case 2 : if ( gcd_get_i2( ccb, (u_i1 *)&u_i2_val ) ) { pre_fetch = max( pre_fetch, u_i2_val ); incomplete = FALSE; } break; case 4 : if ( gcd_get_i4( ccb, (u_i1 *)&u_i4_val ) ) { pre_fetch = max( pre_fetch, u_i4_val ); incomplete = FALSE; } break; } break; case MSG_CUR_POS_ANCHOR : switch( cp.val_len ) { case 1 : if ( gcd_get_i1( ccb, (u_i1 *)&u_i1_val ) ) { pos_anchor = (u_i2)u_i1_val; incomplete = FALSE; } break; case 2 : if ( gcd_get_i2( ccb, (u_i1 *)&u_i2_val ) ) { pos_anchor = (u_i2)u_i2_val; incomplete = FALSE; } break; case 4 : if ( gcd_get_i4( ccb, (u_i1 *)&u_i4_val ) ) { pos_anchor = (u_i2)u_i2_val; incomplete = FALSE; } break; } break; case MSG_CUR_POS_OFFSET : if ( cp.val_len != CV_N_I4_SZ || ! gcd_get_i4( ccb, (u_i1 *)&pos_offset ) ) break; incomplete = FALSE; break; default : if ( GCD_global.gcd_trace_level >= 3 ) TRdisplay( "%4d GCD unkown parameter ID %d\n", ccb->id, cp.param_id ); break; } if ( incomplete ) break; } if ( incomplete ) { if ( GCD_global.gcd_trace_level >= 1 ) TRdisplay( "%4d GCD unable to read all cursor parameters %d\n", ccb->id ); status = E_GC480A_PROTOCOL_ERROR; } else if ( ! got_id ) { if ( GCD_global.gcd_trace_level >= 1 ) TRdisplay( "%4d GCD no cursor ID for cursor message\n", ccb->id ); status = E_GC480A_PROTOCOL_ERROR; } else status = OK; if ( status != OK ) { gcd_del_pcb( pcb ); gcd_sess_abort( ccb, status ); return; } if ( ! (scb = gcd_find_stmt( ccb, &stmt_id )) ) { if ( GCD_global.gcd_trace_level >= 1 ) TRdisplay( "%4d GCD no active statement for cursor ID\n", ccb->id ); gcd_sess_error( ccb, &pcb->rcb, E_GC4811_NO_STMT ); gcd_send_done( ccb, &pcb->rcb, pcb ); gcd_del_pcb( pcb ); gcd_msg_pause( ccb, TRUE ); return; } switch( cursor.cursor_op ) { case MSG_CUR_CLOSE : ccb->sequence = CLOSE_CURSOR; pcb->scb = scb; crsr_close_sm( (PTR)pcb ); break; case MSG_CUR_FETCH : ccb->sequence = FETCH_INIT; ccb->api.stmt = scb->handle; /* Activate statement */ pcb->scb = scb; pcb->data.data.reference = pos_anchor; pcb->data.data.offset = pos_offset; pcb->data.data.max_row = pre_fetch; crsr_fetch_sm( (PTR)pcb ); break; default : if ( GCD_global.gcd_trace_level >= 1 ) TRdisplay( "%4d GCD invalid cursor op: %d\n", ccb->id, cursor.cursor_op ); gcd_del_pcb( pcb ); gcd_sess_abort( ccb, E_GC480A_PROTOCOL_ERROR ); } return; }
static STATUS gcd_api_status( char *func_name, IIAPI_GENPARM *genParm, GCD_CCB *ccb, GCD_RCB **rcb_ptr ) { IIAPI_STATUS api_status = genParm->gp_status; bool api_error = API_ERROR( genParm->gp_status ); bool dbms_error = FALSE; STATUS status = OK; if ( (api_error && GCD_global.gcd_trace_level >= 1) || GCD_global.gcd_trace_level >= 2 ) TRdisplay( "%4d GCD %s status: %s\n", ccb->id, func_name, gcu_lookup( apiMap, genParm->gp_status ) ); if ( genParm->gp_errorHandle ) { IIAPI_GETEINFOPARM get; get.ge_errorHandle = genParm->gp_errorHandle; IIapi_getErrorInfo( &get ); while( get.ge_status == IIAPI_ST_SUCCESS ) { u_i2 msg_len = get.ge_message ? (u_i2)STlength(get.ge_message) : 0; switch( get.ge_type ) { case IIAPI_GE_ERROR : switch( get.ge_errorCode ) { case E_AP0001_CONNECTION_ABORTED : ccb->cib->flags |= GCD_CONN_ABORT; break; case E_AP0002_TRANSACTION_ABORTED : ccb->cib->flags |= GCD_XACT_ABORT; break; case E_AP0003_ACTIVE_TRANSACTIONS : case E_AP0004_ACTIVE_QUERIES : case E_AP0006_INVALID_SEQUENCE : ccb->cib->flags |= GCD_LOGIC_ERR; break; } if ( ! dbms_error ) { status = get.ge_errorCode; dbms_error = TRUE; } if ( GCD_global.gcd_trace_level >= 2 ) TRdisplay( "%4d GCD Error 0x%x '%s'\n", ccb->id, get.ge_errorCode, get.ge_SQLSTATE ); if ( GCD_global.gcd_trace_level >= 3 && get.ge_message ) TRdisplay( "%4d GCD %s\n", ccb->id, get.ge_message ); if ( rcb_ptr ) gcd_send_error( ccb, rcb_ptr, MSG_ET_ERR, get.ge_errorCode, get.ge_SQLSTATE, msg_len, get.ge_message ); break; case IIAPI_GE_XAERR : if ( GCD_global.gcd_trace_level >= 2 ) TRdisplay( "%4d GCD XA Error %d\n", ccb->id, get.ge_errorCode ); if ( ! dbms_error ) { status = FAIL; dbms_error = TRUE; } if ( rcb_ptr ) gcd_send_error( ccb, rcb_ptr, MSG_ET_XA, get.ge_errorCode, get.ge_SQLSTATE, msg_len, get.ge_message ); break; case IIAPI_GE_WARNING : if ( GCD_global.gcd_trace_level >= 2 ) TRdisplay( "%4d GCD Warning 0x%x '%s'\n", ccb->id, get.ge_errorCode, get.ge_SQLSTATE ); if ( GCD_global.gcd_trace_level >= 3 && get.ge_message ) TRdisplay( "%4d GCD %s\n", ccb->id, get.ge_message ); if ( rcb_ptr ) gcd_send_error( ccb, rcb_ptr, MSG_ET_WRN, get.ge_errorCode, get.ge_SQLSTATE, msg_len, get.ge_message ); break; default : if ( GCD_global.gcd_trace_level >= 2 ) TRdisplay( "%4d GCD User Message 0x%x\n", ccb->id, get.ge_errorCode ); if ( GCD_global.gcd_trace_level >= 3 && get.ge_message ) TRdisplay( "%4d GCD %s\n", ccb->id, get.ge_message ); if ( rcb_ptr ) gcd_send_error( ccb, rcb_ptr, MSG_ET_MSG, get.ge_errorCode, get.ge_SQLSTATE, msg_len, get.ge_message ); break; } IIapi_getErrorInfo( &get ); } } if ( dbms_error && ! status ) status = E_GC4809_INTERNAL_ERROR; else if ( api_error && ! dbms_error ) { status = (api_status == IIAPI_ST_OUT_OF_MEMORY) ? E_GC4808_NO_MEMORY : E_GC4809_INTERNAL_ERROR; if ( rcb_ptr ) gcd_sess_error( ccb, rcb_ptr, status ); } return( status ); }