Merge branch 'dev' into feature/20260602_connection_driver_i18n

# Conflicts:
#	shared/i18n/de-DE.json
#	shared/i18n/en-US.json
#	shared/i18n/ja-JP.json
#	shared/i18n/ru-RU.json
#	shared/i18n/zh-CN.json
#	shared/i18n/zh-TW.json
This commit is contained in:
tianqijiuyun-latiao
2026-06-23 16:23:43 +08:00
34 changed files with 30164 additions and 29192 deletions

View File

@@ -8,6 +8,7 @@ import { TabData, ColumnDefinition } from '../types';
import { useStore } from '../store';
import { DBQuery, DBQueryWithCancel, DBQueryMulti, DBQueryMultiTransactional, DBGetTables, DBGetAllColumns, DBGetDatabases, DBGetColumns, CancelQuery, GenerateQueryID, WriteSQLFile, ExportSQLFile } from '../../wailsjs/go/app/App';
import { GONAVI_ROW_KEY } from './DataGrid';
import { findConnectionMutatingStatements } from '../utils/connectionReadOnly';
import { getDataSourceCapabilities, shouldShowOceanBaseRowNumberColumn } from '../utils/dataSourceCapabilities';
import { applyMongoQueryAutoLimit, convertMongoShellToJsonCommand } from "../utils/mongodb";
import { getShortcutDisplayLabel, getShortcutPlatform, getShortcutPrimaryModifierDisplayLabel, isEditableElement, isImeComposingKeyEvent, isShortcutMatch, comboToMonacoKeyBinding, resolveShortcutBinding } from "../utils/shortcuts";
@@ -95,6 +96,7 @@ import {
isDocumentLevelShortcutTarget,
isQueryEditorPrimaryMouseButton,
normalizeCommentText,
normalizeQueryResultMessages,
normalizeCompletionQualifiedName,
normalizeEditorPosition,
normalizeExecutedSqlKey,
@@ -2863,6 +2865,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
const cols = (rsData.columns && rsData.columns.length > 0)
? rsData.columns
: (rows.length > 0 ? Object.keys(rows[0]) : []);
const refreshedMessages = normalizeQueryResultMessages(rsData?.messages);
rows.forEach((row: any, i: number) => {
if (row && typeof row === 'object') row[GONAVI_ROW_KEY] = i;
});
@@ -2874,8 +2877,8 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
...rs,
rows,
columns: cols,
messages: Array.isArray(rsData.messages) ? rsData.messages : [],
resultType: ((!Array.isArray(rsData.rows) || rsData.rows.length === 0) && (!Array.isArray(rsData.columns) || rsData.columns.length === 0) && Array.isArray(rsData.messages) && rsData.messages.length > 0)
messages: refreshedMessages,
resultType: ((!Array.isArray(rsData.rows) || rsData.rows.length === 0) && (!Array.isArray(rsData.columns) || rsData.columns.length === 0) && refreshedMessages.length > 0)
? 'message'
: 'grid',
truncated,
@@ -2957,6 +2960,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
const cols = (rsData.columns && rsData.columns.length > 0)
? rsData.columns
: (rows.length > 0 ? Object.keys(rows[0]) : target.columns);
const pageMessages = normalizeQueryResultMessages(rsData?.messages);
const totalState = resolveQueryResultPaginationTotal({
current: safePage,
pageSize: safePageSize,
@@ -2969,7 +2973,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
...rs,
rows,
columns: cols,
messages: Array.isArray(rsData.messages) ? rsData.messages : [],
messages: pageMessages,
resultType: 'grid',
truncated: false,
page: {
@@ -3031,13 +3035,18 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
return;
}
const connCaps = getDataSourceCapabilities(conn.config);
if (!connCaps.supportsQueryEditor) {
message.error(translate('query_editor.message.unsupported_source'));
if (runSeqRef.current === runSeq) setLoading(false);
return;
}
if (!connCaps.supportsQueryEditor) {
message.error(translate('query_editor.message.unsupported_source'));
if (runSeqRef.current === runSeq) setLoading(false);
return;
}
if (findConnectionMutatingStatements(conn.config, executableSQL).length > 0) {
message.warning(translate('query_editor.message.connection_readonly_blocked'));
if (runSeqRef.current === runSeq) setLoading(false);
return;
}
const config = {
const config = {
...conn.config,
port: Number(conn.config.port),
password: conn.config.password || "",
@@ -3122,6 +3131,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
setQueryId(queryId);
const res = await DBQueryWithCancel(buildRpcConnectionConfig(config) as any, currentDb, executedSql, queryId);
const legacyResultMessages = normalizeQueryResultMessages(res?.messages);
const duration = Date.now() - startTime;
addSqlLog({
id: `log-${Date.now()}-query-${idx + 1}`,
@@ -3165,12 +3175,12 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
statementResultIndex: 1,
rows,
columns: cols,
messages: Array.isArray(res.messages) ? res.messages : [],
messages: legacyResultMessages,
pkColumns: [],
readOnly: true,
truncated
});
} else if (Array.isArray(res.messages) && res.messages.length > 0) {
} else if (legacyResultMessages.length > 0) {
nextResultSets.push({
key: `result-${idx + 1}`,
sql: rawStatement,
@@ -3179,7 +3189,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
statementResultIndex: 1,
rows: [],
columns: [],
messages: res.messages,
messages: legacyResultMessages,
resultType: 'message',
pkColumns: [],
readOnly: true,
@@ -3197,7 +3207,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
statementResultIndex: 1,
rows: [row],
columns: ['affectedRows'],
messages: Array.isArray(res.messages) ? res.messages : [],
messages: legacyResultMessages,
pkColumns: [],
readOnly: true
});
@@ -3413,9 +3423,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
// res.data 是 ResultSetData[] 数组
const resultSetDataArray = Array.isArray(res.data) ? (res.data as any[]) : [];
const topLevelMessages = Array.isArray(res.messages)
? (res.messages as any[]).map((item) => String(item ?? '').trim()).filter(Boolean)
: [];
const topLevelMessages = normalizeQueryResultMessages(res.messages);
const nextResultSets: ResultSet[] = [];
const maxRows = Number(queryOptions?.maxRows) || 0;
let anyTruncated = false;
@@ -3429,7 +3437,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
const plan = executablePlans[Math.max(0, sourceStatementIndex - 1)];
const originalSql = plan?.originalSql || '';
const executedSql = plan?.executedSql || originalSql;
const resultMessages = Array.isArray(rsData?.messages) ? rsData.messages : [];
const resultMessages = normalizeQueryResultMessages(rsData?.messages);
// 检查是否为 affectedRows 类结果集
const isAffectedResult = Array.isArray(rsData.rows) && rsData.rows.length === 1
@@ -3622,10 +3630,10 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
const editorHasFocus = !!editor.hasTextFocus?.();
const inEditorPane = !!(targetNode && editorPaneRef.current?.contains(targetNode));
const inQueryEditor = !!(targetNode && queryEditorRootRef.current?.contains(targetNode));
if (!editorHasFocus && !inEditorPane) {
if (isEditableElement(event.target) && !inEditorPane) {
return;
}
if (!editorHasFocus && isEditableElement(event.target) && !inEditorPane) {
if (!editorHasFocus && !inEditorPane) {
return;
}
if (!editorHasFocus && !inQueryEditor) {