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 ); }
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; }
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); }