🐛 fix(table-designer): 优化表设计触发器修改入口

- 修改触发器从固定弹窗改为对象编辑 SQL 标签页
- 生成删除旧触发器和创建新触发器脚本,便于执行前审查
- 抽出触发器编辑 SQL 构造工具,统一 TriggerViewer 与 TableDesigner 逻辑
- 保留新增触发器原弹窗路径,降低行为变更范围
- 新增触发器编辑入口与 SQL 构造回归测试
Refs #557
This commit is contained in:
Syngnat
2026-06-12 17:39:34 +08:00
parent 8519748512
commit ae2b27c4b4
5 changed files with 128 additions and 29 deletions

View File

@@ -8,17 +8,12 @@ import { DBQuery } from '../../wailsjs/go/app/App';
import { buildRpcConnectionConfig } from '../utils/connectionRpcConfig';
import { normalizeOceanBaseProtocol } from '../utils/oceanBaseProtocol';
import { splitQualifiedNameLast } from '../utils/qualifiedName';
import { buildEditableTriggerSql } from '../utils/triggerEditSql';
interface TriggerViewerProps {
tab: TabData;
}
const ensureSqlStatementTerminator = (sql: string): string => {
const normalized = String(sql || '').trim();
if (!normalized) return '';
return /;\s*$/.test(normalized) ? normalized : `${normalized};`;
};
const getCaseInsensitiveRawValue = (row: Record<string, any>, keys: string[]): any => {
const normalizedKeyMap = new Map<string, string>();
Object.keys(row || {}).forEach((key) => normalizedKeyMap.set(key.toLowerCase(), key));
@@ -105,25 +100,6 @@ const buildOracleLikeTriggerDDLFromMetadata = (
return `CREATE OR REPLACE TRIGGER ${qualifiedTriggerName}\n${triggerType} ${triggeringEvent} ON ${qualifiedTableName}${normalizedWhenClause}\n${triggerBody}`;
};
const buildEditableTriggerSql = (triggerName: string, triggerDefinition: string): string => {
const normalizedName = String(triggerName || '').trim();
const normalizedDefinition = String(triggerDefinition || '').trim();
const header = `-- 修改触发器: ${normalizedName}\n-- \n`;
if (!normalizedDefinition) {
return `${header}-- CREATE TRIGGER \n`;
}
if (/^\s*create\s+(?:or\s+replace\s+)?trigger\b/i.test(normalizedDefinition)) {
return `${header}${ensureSqlStatementTerminator(normalizedDefinition)}`;
}
if (/^\s*trigger\b/i.test(normalizedDefinition)) {
return `${header}${ensureSqlStatementTerminator(normalizedDefinition.replace(/^\s*trigger\b/i, 'CREATE OR REPLACE TRIGGER'))}`;
}
if (/^\s*(?:before|after|instead\s+of)\b/i.test(normalizedDefinition)) {
return `${header}${ensureSqlStatementTerminator(`CREATE OR REPLACE TRIGGER ${normalizedName}\n${normalizedDefinition}`)}`;
}
return `${header}-- CREATE TRIGGER \n${ensureSqlStatementTerminator(normalizedDefinition)}`;
};
const TriggerViewer: React.FC<TriggerViewerProps> = ({ tab }) => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);