mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-30 18:30:39 +08:00
🐛 fix(query-editor): 修复结果集阻塞与未知总数分页误导
- 为查询结果定位元数据探测增加软超时降级,避免租户元数据卡死阻塞主查询结果渲染 - 将未知总数分页切换为顺序翻页模式,并修正文案仅在真实统计时显示正在统计中 - 补充查询结果与分页回归测试,覆盖元数据超时和 legacy 未知总数分页场景
This commit is contained in:
@@ -369,6 +369,7 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = React.memo(({
|
||||
const duckdbApproxKeyRef = useRef<string>('');
|
||||
const oracleApproxSeqRef = useRef(0);
|
||||
const oracleApproxKeyRef = useRef<string>('');
|
||||
const autoCountKeyRef = useRef<string>('');
|
||||
const manualCountSeqRef = useRef(0);
|
||||
const manualCountKeyRef = useRef<string>('');
|
||||
const pkSeqRef = useRef(0);
|
||||
@@ -463,6 +464,7 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = React.memo(({
|
||||
countKeyRef.current = '';
|
||||
duckdbApproxKeyRef.current = '';
|
||||
oracleApproxKeyRef.current = '';
|
||||
autoCountKeyRef.current = '';
|
||||
manualCountKeyRef.current = '';
|
||||
duckdbSafeSelectCacheRef.current = {};
|
||||
latestConfigRef.current = null;
|
||||
@@ -923,7 +925,9 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = React.memo(({
|
||||
return { ...prev, current: currentPage, pageSize: size };
|
||||
}
|
||||
}
|
||||
const keepManualCounting = prev.totalCountLoading && manualCountKeyRef.current === countKey;
|
||||
const keepTotalCounting = prev.totalCountLoading && (
|
||||
manualCountKeyRef.current === countKey || autoCountKeyRef.current === countKey
|
||||
);
|
||||
const hasApproximateTotalForCurrentKey =
|
||||
prev.totalApprox &&
|
||||
(duckdbApproxKeyRef.current === countKey || oracleApproxKeyRef.current === countKey) &&
|
||||
@@ -938,7 +942,7 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = React.memo(({
|
||||
totalKnown: false,
|
||||
totalApprox: true,
|
||||
approximateTotal: prev.approximateTotal,
|
||||
totalCountLoading: keepManualCounting,
|
||||
totalCountLoading: keepTotalCounting,
|
||||
totalCountCancelled: false,
|
||||
};
|
||||
}
|
||||
@@ -950,8 +954,8 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = React.memo(({
|
||||
totalKnown: false,
|
||||
totalApprox: false,
|
||||
approximateTotal: undefined,
|
||||
totalCountLoading: keepManualCounting,
|
||||
totalCountCancelled: keepManualCounting ? false : prev.totalCountCancelled,
|
||||
totalCountLoading: keepTotalCounting,
|
||||
totalCountCancelled: keepTotalCounting ? false : prev.totalCountCancelled,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -959,11 +963,13 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = React.memo(({
|
||||
if (shouldRunAsyncCount) {
|
||||
if (countKeyRef.current !== countKey) {
|
||||
countKeyRef.current = countKey;
|
||||
autoCountKeyRef.current = countKey;
|
||||
const countSeq = ++countSeqRef.current;
|
||||
const countStart = Date.now();
|
||||
// Large-table COUNT(*) can be slow and may delay later operations in some runtimes.
|
||||
// DuckDB large-file scenarios disable background COUNT because it can slow pagination significantly.
|
||||
const countConfig = buildRpcConnectionConfig(config, { timeout: 5 });
|
||||
setPagination(prev => ({ ...prev, totalCountLoading: true, totalCountCancelled: false }));
|
||||
|
||||
DBQuery(countConfig, dbName, countSql)
|
||||
.then((resCount: any) => {
|
||||
@@ -982,11 +988,21 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = React.memo(({
|
||||
if (countSeqRef.current !== countSeq) return;
|
||||
if (latestCountKeyRef.current !== countKey) return;
|
||||
|
||||
if (!resCount.success) return;
|
||||
if (!Array.isArray(resCount.data) || resCount.data.length === 0) return;
|
||||
autoCountKeyRef.current = '';
|
||||
if (!resCount.success) {
|
||||
setPagination(prev => ({ ...prev, totalCountLoading: false }));
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(resCount.data) || resCount.data.length === 0) {
|
||||
setPagination(prev => ({ ...prev, totalCountLoading: false }));
|
||||
return;
|
||||
}
|
||||
|
||||
const total = parseTotalFromCountRow(resCount.data[0]);
|
||||
if (total === null) return;
|
||||
if (total === null) {
|
||||
setPagination(prev => ({ ...prev, totalCountLoading: false }));
|
||||
return;
|
||||
}
|
||||
|
||||
setPagination(prev => ({
|
||||
...prev,
|
||||
@@ -1001,6 +1017,8 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = React.memo(({
|
||||
.catch(() => {
|
||||
if (countSeqRef.current !== countSeq) return;
|
||||
if (countKeyRef.current !== countKey) return;
|
||||
autoCountKeyRef.current = '';
|
||||
setPagination(prev => ({ ...prev, totalCountLoading: false }));
|
||||
// Count failures do not block the main flow; details stay in the SQL log.
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user