mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-13 00:13:33 +08:00
Merge remote-tracking branch 'origin/dev' into feature/20260602_connection_driver_i18n
This commit is contained in:
@@ -843,6 +843,43 @@ describe('QueryEditor external SQL save', () => {
|
|||||||
expect(dataGridState.latestProps?.columnNames).toEqual(['name']);
|
expect(dataGridState.latestProps?.columnNames).toEqual(['name']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('hides redundant sqlserver affected-row status result after a query result', async () => {
|
||||||
|
storeState.connections[0].config.type = 'sqlserver';
|
||||||
|
storeState.connections[0].config.database = 'hydee';
|
||||||
|
backendApp.DBQueryMulti.mockResolvedValueOnce({
|
||||||
|
success: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
statementIndex: 1,
|
||||||
|
columns: ['dddwno', 'dddwlist'],
|
||||||
|
rows: [{ dddwno: '001', dddwlist: 'demo' }],
|
||||||
|
},
|
||||||
|
{ statementIndex: 1, columns: ['affectedRows'], rows: [{ affectedRows: 846 }] },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
let renderer!: ReactTestRenderer;
|
||||||
|
await act(async () => {
|
||||||
|
renderer = create(<QueryEditor tab={createTab({ dbName: 'hydee', query: 'select * from c_dddw' })} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await findButton(renderer!, '运行').props.onClick();
|
||||||
|
});
|
||||||
|
await act(async () => {
|
||||||
|
await Promise.resolve();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
const rendered = textContent(renderer!.toJSON());
|
||||||
|
expect(rendered).toContain('结果 1');
|
||||||
|
expect(rendered).not.toContain('结果 2');
|
||||||
|
expect(rendered).not.toContain('影响行数:846');
|
||||||
|
expect(dataGridState.latestProps?.columnNames).toEqual(['dddwno', 'dddwlist']);
|
||||||
|
expect(dataGridState.latestProps?.data?.[0]).toMatchObject({ dddwno: '001', dddwlist: 'demo' });
|
||||||
|
expect(messageApi.success).toHaveBeenCalledWith('已执行完成,生成 1 个结果集。');
|
||||||
|
});
|
||||||
|
|
||||||
it('prefers the first displayable sqlserver procedure result when empty result sets are returned', async () => {
|
it('prefers the first displayable sqlserver procedure result when empty result sets are returned', async () => {
|
||||||
storeState.connections[0].config.type = 'sqlserver';
|
storeState.connections[0].config.type = 'sqlserver';
|
||||||
storeState.connections[0].config.database = 'hydee';
|
storeState.connections[0].config.database = 'hydee';
|
||||||
@@ -953,7 +990,7 @@ describe('QueryEditor external SQL save', () => {
|
|||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(textContent(renderer!.toJSON())).toContain('消息 2');
|
expect(textContent(renderer!.toJSON())).toContain('消息 1');
|
||||||
expect(findResultMessageTextarea(renderer!).props.value).toBe([
|
expect(findResultMessageTextarea(renderer!).props.value).toBe([
|
||||||
"insert into c_dyscript(projectid,name) values (1,'demo')",
|
"insert into c_dyscript(projectid,name) values (1,'demo')",
|
||||||
"insert into c_dyscript(projectid,name) values (2,'next')",
|
"insert into c_dyscript(projectid,name) values (2,'next')",
|
||||||
@@ -1033,7 +1070,7 @@ describe('QueryEditor external SQL save', () => {
|
|||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(textContent(renderer!.toJSON())).toContain('消息 2');
|
expect(textContent(renderer!.toJSON())).toContain('消息 1');
|
||||||
expect(findResultMessageTextarea(renderer!).props.value).toBe("insert into c_dyscript(projectid,name) values (1,'demo')");
|
expect(findResultMessageTextarea(renderer!).props.value).toBe("insert into c_dyscript(projectid,name) values (1,'demo')");
|
||||||
expect(textContent(renderer!.toJSON())).not.toContain('影响行数:0');
|
expect(textContent(renderer!.toJSON())).not.toContain('影响行数:0');
|
||||||
expect(dataGridState.latestProps).toBeNull();
|
expect(dataGridState.latestProps).toBeNull();
|
||||||
|
|||||||
@@ -2777,6 +2777,24 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
|
|||||||
result.columns[0] === 'affectedRows',
|
result.columns[0] === 'affectedRows',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isAffectedRowsResultSetData = (result?: any): boolean =>
|
||||||
|
Boolean(
|
||||||
|
result &&
|
||||||
|
Array.isArray(result.rows) &&
|
||||||
|
result.rows.length === 1 &&
|
||||||
|
Array.isArray(result.columns) &&
|
||||||
|
result.columns.length === 1 &&
|
||||||
|
result.columns[0] === 'affectedRows',
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasConcreteQueryResultSetData = (result: any, messages: string[]): boolean => {
|
||||||
|
if (!result || isAffectedRowsResultSetData(result)) return false;
|
||||||
|
if (messages.length > 0) return true;
|
||||||
|
if (Array.isArray(result.columns) && result.columns.length > 0) return true;
|
||||||
|
if (Array.isArray(result.rows) && result.rows.length > 0) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
const isMessageLikeResultSet = (result?: ResultSet | null): boolean =>
|
const isMessageLikeResultSet = (result?: ResultSet | null): boolean =>
|
||||||
Boolean(
|
Boolean(
|
||||||
result &&
|
result &&
|
||||||
@@ -3492,28 +3510,49 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
|
|||||||
const maxRows = Number(queryOptions?.maxRows) || 0;
|
const maxRows = Number(queryOptions?.maxRows) || 0;
|
||||||
let anyTruncated = false;
|
let anyTruncated = false;
|
||||||
const statementResultCounts = new Map<number, number>();
|
const statementResultCounts = new Map<number, number>();
|
||||||
|
const sqlServerStatementsWithConcreteResults = new Set<number>();
|
||||||
|
if (normalizedDbType === 'sqlserver') {
|
||||||
|
resultSetDataArray.forEach((rsData, idx) => {
|
||||||
|
const sourceStatementIndex = Number(rsData?.statementIndex || idx + 1);
|
||||||
|
const resultMessages = normalizeQueryResultMessages(rsData?.messages);
|
||||||
|
if (hasConcreteQueryResultSetData(rsData, resultMessages)) {
|
||||||
|
sqlServerStatementsWithConcreteResults.add(sourceStatementIndex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const shouldUseTopLevelSqlServerMessages = normalizedDbType === 'sqlserver'
|
||||||
|
&& topLevelMessages.length > 0
|
||||||
|
&& sqlServerStatementsWithConcreteResults.size === 0;
|
||||||
|
|
||||||
for (let idx = 0; idx < resultSetDataArray.length; idx++) {
|
for (let idx = 0; idx < resultSetDataArray.length; idx++) {
|
||||||
const rsData = resultSetDataArray[idx];
|
const rsData = resultSetDataArray[idx];
|
||||||
const sourceStatementIndex = Number(rsData?.statementIndex || idx + 1);
|
const sourceStatementIndex = Number(rsData?.statementIndex || idx + 1);
|
||||||
const statementResultIndex = (statementResultCounts.get(sourceStatementIndex) || 0) + 1;
|
|
||||||
statementResultCounts.set(sourceStatementIndex, statementResultIndex);
|
|
||||||
const plan = executablePlans[Math.max(0, sourceStatementIndex - 1)];
|
const plan = executablePlans[Math.max(0, sourceStatementIndex - 1)];
|
||||||
const originalSql = plan?.originalSql || '';
|
const originalSql = plan?.originalSql || '';
|
||||||
const executedSql = plan?.executedSql || originalSql;
|
const executedSql = plan?.executedSql || originalSql;
|
||||||
const resultMessages = normalizeQueryResultMessages(rsData?.messages);
|
const resultMessages = normalizeQueryResultMessages(rsData?.messages);
|
||||||
|
|
||||||
// 检查是否为 affectedRows 类结果集
|
// 检查是否为 affectedRows 类结果集
|
||||||
const isAffectedResult = Array.isArray(rsData.rows) && rsData.rows.length === 1
|
const isAffectedResult = isAffectedRowsResultSetData(rsData);
|
||||||
&& rsData.columns && rsData.columns.length === 1
|
const shouldHideSqlServerAffectedResult = normalizedDbType === 'sqlserver'
|
||||||
&& rsData.columns[0] === 'affectedRows';
|
&& isAffectedResult
|
||||||
|
&& (
|
||||||
|
sqlServerStatementsWithConcreteResults.has(sourceStatementIndex)
|
||||||
|
|| shouldUseTopLevelSqlServerMessages
|
||||||
|
);
|
||||||
|
if (shouldHideSqlServerAffectedResult) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const statementResultIndex = (statementResultCounts.get(sourceStatementIndex) || 0) + 1;
|
||||||
|
statementResultCounts.set(sourceStatementIndex, statementResultIndex);
|
||||||
|
|
||||||
if (isAffectedResult) {
|
if (isAffectedResult) {
|
||||||
const affected = Number(rsData.rows[0]?.affectedRows);
|
const affected = Number(rsData.rows[0]?.affectedRows);
|
||||||
const row = { affectedRows: Number.isFinite(affected) ? affected : 0 };
|
const row = { affectedRows: Number.isFinite(affected) ? affected : 0 };
|
||||||
(row as any)[GONAVI_ROW_KEY] = 0;
|
(row as any)[GONAVI_ROW_KEY] = 0;
|
||||||
nextResultSets.push({
|
nextResultSets.push({
|
||||||
key: `result-${idx + 1}`,
|
key: `result-${nextResultSets.length + 1}`,
|
||||||
sql: executedSql,
|
sql: executedSql,
|
||||||
exportSql: originalSql,
|
exportSql: originalSql,
|
||||||
sourceStatementIndex,
|
sourceStatementIndex,
|
||||||
@@ -3526,7 +3565,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
|
|||||||
});
|
});
|
||||||
} else if ((!Array.isArray(rsData.rows) || rsData.rows.length === 0) && (!Array.isArray(rsData.columns) || rsData.columns.length === 0) && resultMessages.length > 0) {
|
} else if ((!Array.isArray(rsData.rows) || rsData.rows.length === 0) && (!Array.isArray(rsData.columns) || rsData.columns.length === 0) && resultMessages.length > 0) {
|
||||||
nextResultSets.push({
|
nextResultSets.push({
|
||||||
key: `result-${idx + 1}`,
|
key: `result-${nextResultSets.length + 1}`,
|
||||||
sql: executedSql,
|
sql: executedSql,
|
||||||
exportSql: originalSql,
|
exportSql: originalSql,
|
||||||
sourceStatementIndex,
|
sourceStatementIndex,
|
||||||
@@ -3566,7 +3605,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
|
|||||||
fallbackPageSize: maxRows,
|
fallbackPageSize: maxRows,
|
||||||
});
|
});
|
||||||
nextResultSets.push({
|
nextResultSets.push({
|
||||||
key: `result-${idx + 1}`,
|
key: `result-${nextResultSets.length + 1}`,
|
||||||
sql: executedSql,
|
sql: executedSql,
|
||||||
exportSql: originalSql,
|
exportSql: originalSql,
|
||||||
sourceStatementIndex,
|
sourceStatementIndex,
|
||||||
|
|||||||
Reference in New Issue
Block a user