Display a confirmation message for the server-side cursor transaction status when closing the query tool.

Resolve the pagination issue by fetching an additional row to determine the availability of the next record set when using a server-side cursor.
pull/8956/head
Khushboo Vashi 2025-07-15 06:21:14 +00:00 committed by GitHub
parent 13ade4c0b2
commit 8c662424b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 10 deletions

View File

@ -1252,8 +1252,12 @@ def fetch_window(trans_id, from_rownum=0, to_rownum=0):
if status and conn is not None and session_obj is not None:
# rownums start from 0 but UI will ask from 1
# to_rownum: Fetch 1 extra row to check whether next
# recordset is available or not, this is required for server cursor.
status, result = conn.async_fetchmany_2darray(
records=None, from_rownum=from_rownum - 1, to_rownum=to_rownum - 1)
records=None, from_rownum=from_rownum - 1, to_rownum=to_rownum if
trans_obj.server_cursor else to_rownum - 1)
if not status:
status = 'Error'
else:
@ -1270,14 +1274,22 @@ def fetch_window(trans_id, from_rownum=0, to_rownum=0):
result = error_msg
page_size = to_rownum - from_rownum + 1
# Check whether the next recordset/page is available or not
next_page = 0
if trans_obj.server_cursor and len(result) > 0 and len(result) > page_size:
result = result[0:len(result) - 1]
next_page = 1
rows_fetched_to = rows_fetched_to - 1
pagination = {
'page_size': page_size,
'page_count': math.ceil(conn.total_rows / page_size),
'page_no': math.floor((rows_fetched_from - 1) / page_size) + 1,
'rows_from': rows_fetched_from,
'rows_to': rows_fetched_to
'rows_to': rows_fetched_to,
'next_page': next_page
}
return make_json_response(
data={
'status': status,

View File

@ -249,11 +249,17 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
return;
}
}
let _confirm_msg = gettext('The current transaction is not committed to the database. '
+'Do you want to commit or rollback the transaction?');
if (queryToolCtx.server_cursor) {
_confirm_msg = gettext('The query was executed with a server-side cursor, '
+ 'which runs within a transaction.') + _confirm_msg;
}
queryToolCtx.modal.showModal(gettext('Commit transaction?'), (closeModal)=>(
<ConfirmTransactionContent
closeModal={closeModal}
text={gettext('The current transaction is not committed to the database. '
+'Do you want to commit or rollback the transaction?')}
text={_confirm_msg}
onRollback={()=>{
onExecutionDone();
onRollbackClick();
@ -267,8 +273,8 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
};
useEffect(()=>{
if(isInTxn()) {
setDisableButton('commit', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ?true:false);
setDisableButton('rollback', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ?true:false);
setDisableButton('commit', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ? true : false);
setDisableButton('rollback', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ? true : false);
setDisableButton('execute-options', true);
} else {
setDisableButton('commit', true);

View File

@ -228,15 +228,14 @@ function PaginationInputs({pagination, totalRowCount, clearSelection, serverCurs
value={inputs.pageNo}
onChange={(value)=>onInputChange('pageNo', value)}
onKeyDown={onInputKeydownPageNo}
disabled={serverCursor}
error={errorInputs['pageNo']}
/>
<span> {gettext('of')} {pagination.page_count}</span>
<div className='PaginationInputs-divider'>&nbsp;</div>
<PgButtonGroup size="small">
<PgIconButton title={gettext('First Page')} disabled={pagination.page_no <= 1 || serverCursor} onClick={()=>goToPage(1)} icon={<SkipPreviousRoundedIcon />}/>
<PgIconButton title={gettext('First Page')} disabled={pagination.page_no <= 1} onClick={()=>goToPage(1)} icon={<SkipPreviousRoundedIcon />}/>
<PgIconButton title={gettext('Previous Page')} disabled={pagination.page_no <= 1} onClick={()=>goToPage(pagination.page_no-1)} icon={<FastRewindRoundedIcon />}/>
<PgIconButton title={gettext('Next Page')} disabled={pagination.page_no == pagination.page_count && !serverCursor} onClick={()=>goToPage(pagination.page_no+1)} icon={<FastForwardRoundedIcon />}/>
<PgIconButton title={gettext('Next Page')} disabled={(pagination.page_no == pagination.page_count && !serverCursor) || (serverCursor && pagination.next_page == 0)} onClick={()=>goToPage(pagination.page_no+1)} icon={<FastForwardRoundedIcon />}/>
<PgIconButton title={gettext('Last Page')} disabled={pagination.page_no == pagination.page_count || serverCursor} onClick={()=>goToPage(pagination.page_count)} icon={<SkipNextRoundedIcon />} />
</PgButtonGroup>
</Box>