Skip to content

Commit 18f8fac

Browse files
committed
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.
1 parent 8723896 commit 18f8fac

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

web/pgadmin/tools/sqleditor/__init__.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,8 +1256,10 @@ def fetch_window(trans_id, from_rownum=0, to_rownum=0):
12561256

12571257
if status and conn is not None and session_obj is not None:
12581258
# rownums start from 0 but UI will ask from 1
1259+
# to_rownum: Fetch 1 extra row to check whether next
1260+
# recordset is available or not, this is required for server cursor.
12591261
status, result = conn.async_fetchmany_2darray(
1260-
records=None, from_rownum=from_rownum - 1, to_rownum=to_rownum - 1)
1262+
records=None, from_rownum=from_rownum - 1, to_rownum=to_rownum)
12611263
if not status:
12621264
status = 'Error'
12631265
else:
@@ -1274,14 +1276,21 @@ def fetch_window(trans_id, from_rownum=0, to_rownum=0):
12741276
result = error_msg
12751277

12761278
page_size = to_rownum - from_rownum + 1
1279+
1280+
# Check whether the next recordset/page is available or not
1281+
next_page = 0
1282+
if len(result) > 0 and len(result) > page_size:
1283+
result = result[0:len(result)-1]
1284+
next_page = 1
1285+
12771286
pagination = {
12781287
'page_size': page_size,
12791288
'page_count': math.ceil(conn.total_rows / page_size),
12801289
'page_no': math.floor((rows_fetched_from - 1) / page_size) + 1,
12811290
'rows_from': rows_fetched_from,
1282-
'rows_to': rows_fetched_to
1291+
'rows_to': rows_fetched_to,
1292+
'next_page': next_page
12831293
}
1284-
12851294
return make_json_response(
12861295
data={
12871296
'status': status,

web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,17 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
249249
return;
250250
}
251251
}
252+
let _confirm_msg = gettext('The current transaction is not committed to the database. '
253+
+'Do you want to commit or rollback the transaction?');
254+
if (queryToolCtx.server_cursor) {
255+
_confirm_msg = gettext('The query was executed with a server-side cursor, '
256+
+ 'which runs within a transaction.') + _confirm_msg;
257+
}
258+
252259
queryToolCtx.modal.showModal(gettext('Commit transaction?'), (closeModal)=>(
253260
<ConfirmTransactionContent
254261
closeModal={closeModal}
255-
text={gettext('The current transaction is not committed to the database. '
256-
+'Do you want to commit or rollback the transaction?')}
262+
text={_confirm_msg}
257263
onRollback={()=>{
258264
onExecutionDone();
259265
onRollbackClick();
@@ -267,8 +273,8 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
267273
};
268274
useEffect(()=>{
269275
if(isInTxn()) {
270-
setDisableButton('commit', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ?true:false);
271-
setDisableButton('rollback', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ?true:false);
276+
setDisableButton('commit', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ? true : false);
277+
setDisableButton('rollback', queryToolCtx.params.server_cursor && !queryToolCtx.params.is_query_tool ? true : false);
272278
setDisableButton('execute-options', true);
273279
} else {
274280
setDisableButton('commit', true);

web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,14 @@ function PaginationInputs({pagination, totalRowCount, clearSelection, serverCurs
228228
value={inputs.pageNo}
229229
onChange={(value)=>onInputChange('pageNo', value)}
230230
onKeyDown={onInputKeydownPageNo}
231-
disabled={serverCursor}
232231
error={errorInputs['pageNo']}
233232
/>
234233
<span> {gettext('of')} {pagination.page_count}</span>
235234
<div className='PaginationInputs-divider'>&nbsp;</div>
236235
<PgButtonGroup size="small">
237-
<PgIconButton title={gettext('First Page')} disabled={pagination.page_no <= 1 || serverCursor} onClick={()=>goToPage(1)} icon={<SkipPreviousRoundedIcon />}/>
236+
<PgIconButton title={gettext('First Page')} disabled={pagination.page_no <= 1} onClick={()=>goToPage(1)} icon={<SkipPreviousRoundedIcon />}/>
238237
<PgIconButton title={gettext('Previous Page')} disabled={pagination.page_no <= 1} onClick={()=>goToPage(pagination.page_no-1)} icon={<FastRewindRoundedIcon />}/>
239-
<PgIconButton title={gettext('Next Page')} disabled={pagination.page_no == pagination.page_count && !serverCursor} onClick={()=>goToPage(pagination.page_no+1)} icon={<FastForwardRoundedIcon />}/>
238+
<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 />}/>
240239
<PgIconButton title={gettext('Last Page')} disabled={pagination.page_no == pagination.page_count || serverCursor} onClick={()=>goToPage(pagination.page_count)} icon={<SkipNextRoundedIcon />} />
241240
</PgButtonGroup>
242241
</Box>

0 commit comments

Comments
 (0)