SQLRETURN CLExtendedFetch(
    SQLHSTMT           statement_handle,
    SQLUSMALLINT       f_fetch_type,
    SQLLEN             irow,
    SQLULEN            *pcrow,
    SQLUSMALLINT       *rgf_row_status )
{
    CLHSTMT cl_statement = (CLHSTMT) statement_handle; 

    if ( !cl_statement -> bound_columns )
    {
        cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error,
                ERROR_SL009, NULL,
                cl_statement -> dm_statement -> connection ->
                    environment -> requested_version );

        return SQL_ERROR;
    }

    return do_fetch_scroll( cl_statement,
            f_fetch_type, 
            irow,
            rgf_row_status,
            pcrow,
			1 );
}
Beispiel #2
0
SQLRETURN api::fetch_scroll(SQLHSTMT statement_handle, SQLSMALLINT fetch_orientation, SQLLEN fetch_offset) const
{
	return do_fetch_scroll(statement_handle, fetch_orientation, fetch_offset);
}
SQLRETURN do_fetch_scroll( CLHSTMT cl_statement,
        int fetch_orientation,
        SQLLEN fetch_offset,
        SQLUSMALLINT *row_status_ptr,
        SQLULEN *rows_fetched_ptr,
		int ext_fetch )
{
    SQLRETURN ret;
    int rows_in_set, row_offset, fetched_rows, info = 0;

	cl_statement -> fetch_done = 1;

    if ( !cl_statement -> first_fetch_done )
    {
        if ( cl_statement -> column_count > 0 && 
                calculate_buffers( cl_statement,
                    cl_statement -> column_count ) == SQL_ERROR )
        {
            /*
             * tidy up after a failure
             */

            SQLFREESTMT( cl_statement -> cl_connection,
                    cl_statement -> driver_stmt,
                    SQL_CLOSE );

            return SQL_ERROR;
        }
        cl_statement -> first_fetch_done = 1;
    }

	if ( ext_fetch ) 
	{
    	if ( cl_statement -> rowset_size < 1 )
       	 	rows_in_set = 1;
    	else 
        	rows_in_set = cl_statement -> rowset_size;
	}
	else 
	{
    	if ( cl_statement -> rowset_array_size < 1 )
       	 	rows_in_set = 1;
    	else 
        	rows_in_set = cl_statement -> rowset_array_size;
	}

    /*
     * I refuse to document all these conditions, you have to
     * look in the book, its just a copy of that
     */

    switch( fetch_orientation )
    {
      case SQL_FETCH_FIRST:
        cl_statement -> rowset_position = 0;
        row_offset = 0;
        cl_statement -> curr_rowset_start = cl_statement -> rowset_position;
        ret = fetch_rowset( cl_statement, rows_in_set, row_offset,
                &fetched_rows, row_status_ptr, rows_fetched_ptr );
        if ( SQL_SUCCEEDED( ret ))
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_position;
            cl_statement -> rowset_position += fetched_rows;
        }
		else if ( ret == SQL_FETCH_PART_ROWSET ) 
		{
			ret = SQL_SUCCESS;
		}
        break;

      case SQL_FETCH_NEXT:
        if ( cl_statement -> rowset_position == CL_BEFORE_START )
        {
            cl_statement -> rowset_position = 0;
            row_offset = 0;
        }
        else if ( cl_statement -> rowset_position == CL_AFTER_END )
        {
            ret = SQL_NO_DATA;
            break;
        }
        else
        {
            row_offset = cl_statement -> rowset_position;
        }

        cl_statement -> cursor_pos = 1;

        ret = fetch_rowset( cl_statement, rows_in_set, row_offset,
                &fetched_rows, row_status_ptr, rows_fetched_ptr );

        if ( SQL_SUCCEEDED( ret ))
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_position;
            cl_statement -> rowset_position += fetched_rows;
        }
		else if ( ret == SQL_FETCH_PART_ROWSET ) 
		{
        	cl_statement -> rowset_position = CL_AFTER_END;
			ret = SQL_SUCCESS;
		}
        break;

      case SQL_FETCH_PRIOR:
        if ( cl_statement -> rowset_position == CL_BEFORE_START )
        {
            ret = SQL_NO_DATA;
            break;
        }
        else if ( cl_statement -> rowset_position == CL_AFTER_END )
        {
            if ( cl_statement -> rowset_count < rows_in_set )
            {
                cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error,
                        ERROR_01S06, NULL,
                        cl_statement -> dm_statement -> connection ->
                            environment -> requested_version );
                info = 1;
            }
            else
            {
                row_offset = cl_statement -> rowset_count - rows_in_set;
	    	cl_statement -> rowset_position = row_offset;
            }
        }
        else if ( cl_statement -> rowset_position <= rows_in_set  )
        {
            ret = SQL_NO_DATA;
            cl_statement -> rowset_position = CL_BEFORE_START;
            break;
        }
        else if ( cl_statement -> rowset_position - rows_in_set < rows_in_set )
        {
            cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error,
                    ERROR_01S06, NULL,
                    cl_statement -> dm_statement -> connection ->
                        environment -> requested_version );
            ret = SQL_SUCCESS_WITH_INFO;
            break;
        }
        else
        {
            row_offset = cl_statement -> rowset_position -= rows_in_set * 2;
        }

        cl_statement -> cursor_pos = 1;

        ret = fetch_rowset( cl_statement, rows_in_set, row_offset,
                &fetched_rows, row_status_ptr, rows_fetched_ptr );

        if ( SQL_SUCCEEDED( ret ))
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_position;
            cl_statement -> rowset_position += fetched_rows;
        }
		else if ( ret == SQL_FETCH_PART_ROWSET ) 
		{
			ret = SQL_SUCCESS;
		}
        break;

      case SQL_FETCH_RELATIVE:
        if (( cl_statement -> rowset_position == CL_BEFORE_START && 
                fetch_offset > 0 ) ||
            ( cl_statement -> rowset_position == CL_AFTER_END && 
                fetch_offset < 0 ))
        {
            return do_fetch_scroll( cl_statement,
                    SQL_FETCH_ABSOLUTE,
                    fetch_offset,
                    row_status_ptr,
                    rows_fetched_ptr, 
					ext_fetch );
        }
        else if ( cl_statement -> rowset_position == CL_BEFORE_START &&
            fetch_offset <= 0 )
        {
            ret = SQL_NO_DATA;
            cl_statement -> rowset_position = CL_BEFORE_START;
            break;
        }
        else if ( cl_statement -> curr_rowset_start == 0 &&
                fetch_offset <= 0 )
        {
            ret = SQL_NO_DATA;
            cl_statement -> rowset_position = CL_BEFORE_START;
            break;
        }
        else if ( cl_statement -> curr_rowset_start > 0 &&
                cl_statement -> curr_rowset_start + fetch_offset < 1 &&
                ABS( fetch_offset ) > rows_in_set )
        {
            ret = SQL_NO_DATA;
            cl_statement -> rowset_position = CL_BEFORE_START;
            break;
        }
        else if ( cl_statement -> curr_rowset_start > 0 &&
                cl_statement -> curr_rowset_start + fetch_offset < 1 &&
                ABS( fetch_offset ) > rows_in_set )
        {
            cl_statement -> rowset_position = 0;
        }
        else
        {
            /*
             * these conditions requires completing the rowset
             */
            if ( !cl_statement -> rowset_complete )
            {
                ret = complete_rowset( cl_statement, 0 );
                if ( !SQL_SUCCEEDED( ret ))
                    break;
            }
            if ( 1 <= cl_statement -> curr_rowset_start + fetch_offset &&
                    cl_statement -> curr_rowset_start + fetch_offset <= 
                    cl_statement -> rowset_count )
            {
                cl_statement -> curr_rowset_start = 
                    cl_statement -> rowset_position = 
                        cl_statement -> curr_rowset_start + fetch_offset;
            }
            else if ( cl_statement -> curr_rowset_start + fetch_offset > 
                    cl_statement -> rowset_count )
            {
                ret = SQL_NO_DATA;
                cl_statement -> rowset_position = CL_AFTER_END;
                break;
            }
            else if ( cl_statement -> rowset_position == CL_AFTER_END &&
                    fetch_offset >= 0 )
            {
                ret = SQL_NO_DATA;
                cl_statement -> rowset_position = CL_AFTER_END;
                break;
            }
        }

        row_offset = cl_statement -> rowset_position;
        cl_statement -> cursor_pos = 1;

        ret = fetch_rowset( cl_statement, rows_in_set, row_offset,
                &fetched_rows, row_status_ptr, rows_fetched_ptr );

        if ( SQL_SUCCEEDED( ret ))
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_position;
            cl_statement -> rowset_position += fetched_rows;
        }
		else if ( ret == SQL_FETCH_PART_ROWSET ) 
		{
			ret = SQL_SUCCESS;
		}

        break;

      /*
       * The code before this turns the bookmark into a absolute
       */
      case SQL_FETCH_BOOKMARK:
      case SQL_FETCH_ABSOLUTE:
        /*
         * close the rowset if needed
         */
        if ( fetch_offset < 0 && !cl_statement -> rowset_complete )
        {
            ret = complete_rowset( cl_statement, 0 );
            if ( !SQL_SUCCEEDED( ret ))
                break;
        }

        if ( fetch_offset < 0 && 
                ABS( fetch_offset ) <= cl_statement -> rowset_count )
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_count + fetch_offset;
            cl_statement -> rowset_position = 
                cl_statement -> curr_rowset_start;
        }
        else if ( fetch_offset < 0 && 
                    ABS( fetch_offset ) >  cl_statement -> rowset_count &&
                    ABS( fetch_offset ) > rows_in_set )
        {
            cl_statement -> rowset_position = CL_BEFORE_START;
            ret = SQL_NO_DATA;
            break;
        }
        else if ( fetch_offset < 0 && 
                    ABS( fetch_offset ) >  cl_statement -> rowset_count &&
                    ABS( fetch_offset ) <= rows_in_set )
        {
            cl_statement -> curr_rowset_start = 0;
            cl_statement -> rowset_position = 
                cl_statement -> curr_rowset_start;

            cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error,
                    ERROR_01S06, NULL,
                    cl_statement -> dm_statement -> connection ->
                        environment -> requested_version );
            info = 1;
        }
        else if ( fetch_offset == 0 )
        {
            cl_statement -> rowset_position = CL_BEFORE_START;
            ret = SQL_NO_DATA;
            break;
        }
        else if ( fetch_offset > cl_statement -> rowset_count )
        {
            ret = complete_rowset( cl_statement, fetch_offset );
            if ( ret == SQL_NO_DATA )
            {
                cl_statement -> rowset_position = CL_AFTER_END;
                break;
            }
            else if ( !SQL_SUCCEEDED( ret ))
            {
                break;
            }
            else
            {
                cl_statement -> curr_rowset_start = fetch_offset;
                cl_statement -> rowset_position = 
                    cl_statement -> curr_rowset_start;
            }
        }
        else
        {
            cl_statement -> curr_rowset_start = fetch_offset;
            cl_statement -> rowset_position = 
                cl_statement -> curr_rowset_start;
        }

        row_offset = cl_statement -> rowset_position - 1;
        cl_statement -> cursor_pos = 1;

        ret = fetch_rowset( cl_statement, rows_in_set, row_offset,
                &fetched_rows, row_status_ptr, rows_fetched_ptr );

        if ( SQL_SUCCEEDED( ret ))
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_position;
            cl_statement -> rowset_position += fetched_rows;
        }
		else if ( ret == SQL_FETCH_PART_ROWSET ) 
		{
			ret = SQL_SUCCESS;
		}

        break;

      case SQL_FETCH_LAST:
        /*
         * close the rowset if needed
         */
        if ( !cl_statement -> rowset_complete )
        {
            ret = complete_rowset( cl_statement, 0 );
            if ( !SQL_SUCCEEDED( ret ))
                break;
        }

        if ( cl_statement -> rowset_count <= rows_in_set )
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_position = 0;
        }
        else
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_position = 
                cl_statement -> rowset_count - rows_in_set;
        }
        row_offset = cl_statement -> rowset_position;
        cl_statement -> cursor_pos = 1;

        ret = fetch_rowset( cl_statement, rows_in_set, row_offset,
                &fetched_rows, row_status_ptr, rows_fetched_ptr );

        if ( SQL_SUCCEEDED( ret ))
        {
            cl_statement -> curr_rowset_start = 
                cl_statement -> rowset_position = CL_AFTER_END;
        }
		else if ( ret == SQL_FETCH_PART_ROWSET ) 
		{
			ret = SQL_SUCCESS;
		}
        
        break;
    }

    if ( ret == SQL_SUCCESS && info )
        ret = SQL_SUCCESS_WITH_INFO;

    return ret;
}
Beispiel #4
0
bool api::fetch_scroll(statement_handle const & statement_handle, SQLSMALLINT fetch_orientation, SQLLEN fetch_offset) const
{
	return do_fetch_scroll(statement_handle, fetch_orientation, fetch_offset);
}