Beispiel #1
0
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;
}
Beispiel #2
0
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 );
}