feat(editor): preview dml changes as readonly select
This commit is contained in:
1 parent
d59b86bd57
commit
333c3a3f44
25 files changed
+848
-4
No files matched your search
@@ -272,6 +272,7 @@ export const prepareDataGridSave = forward("prepareDataGridSave");
|
||||
export const extractDataGridSelection = forward("extractDataGridSelection");
|
||||
export const buildDataGridCopyUpdateStatements = forward("buildDataGridCopyUpdateStatements");
|
||||
export const buildDataGridCopyInsertStatement = forward("buildDataGridCopyInsertStatement");
|
||||
export const buildDmlChangePreviewSql = forward("buildDmlChangePreviewSql");
|
||||
export const buildDataGridContextFilterCondition = forward("buildDataGridContextFilterCondition");
|
||||
export const buildDataGridColumnValueFilterCondition = forward("buildDataGridColumnValueFilterCondition");
|
||||
export const buildDataGridColumnValuesFilterCondition = forward("buildDataGridColumnValuesFilterCondition");
|
||||
|
||||
@@ -165,6 +165,7 @@ import type {
|
||||
DataGridSaveStatementOptions,
|
||||
HiveTablePropertiesSqlOptions,
|
||||
} from "@/lib/dataGrid/dataGridSql";
|
||||
import type { DmlChangePreviewSqlOptions, DmlChangePreviewSqlResult } from "@/lib/sql/dmlChangePreview";
|
||||
import type { DataGridExtractRequest, DataGridExtractResult } from "@/lib/dataGrid/dataGridCopyExtractor";
|
||||
import type { BuildTableOwnerChangeSqlOptions, BuildTableStructureChangeSqlOptions, BuildSingleColumnAlterSqlOptions, SqliteTableStructureChangePreview, TableStructureChangeSql } from "@/lib/table/tableStructureEditorSql";
|
||||
import type { BuildTableSelectSqlOptions } from "@/lib/table/tableSelectSql";
|
||||
@@ -1527,6 +1528,10 @@ export async function buildDataGridCopyInsertStatement(options: DataGridCopyInse
|
||||
return result ?? undefined;
|
||||
}
|
||||
|
||||
export async function buildDmlChangePreviewSql(options: DmlChangePreviewSqlOptions): Promise<DmlChangePreviewSqlResult> {
|
||||
return post("/api/query/build-dml-change-preview-sql", { options });
|
||||
}
|
||||
|
||||
export async function buildDataGridContextFilterCondition(options: DataGridContextFilterConditionOptions): Promise<string | undefined> {
|
||||
const result = await post<string | null>("/api/query/build-data-grid-context-filter-condition", { options });
|
||||
return result ?? undefined;
|
||||
|
||||
@@ -84,6 +84,7 @@ import type {
|
||||
DataGridSaveStatementOptions,
|
||||
HiveTablePropertiesSqlOptions,
|
||||
} from "@/lib/dataGrid/dataGridSql";
|
||||
import type { DmlChangePreviewSqlOptions, DmlChangePreviewSqlResult } from "@/lib/sql/dmlChangePreview";
|
||||
import type { DataGridExtractRequest, DataGridExtractResult } from "@/lib/dataGrid/dataGridCopyExtractor";
|
||||
import type { DataCompareFromTablesOptions, DataCompareFromTablesPreparation, DataCompareSyncPlan, DataCompareSyncPlanOptions, DataComparePreparation, DataComparePreparationOptions } from "@/lib/dataGrid/dataCompare";
|
||||
import type { SchemaDiffPreparation, SchemaDiffPreparationOptions, SchemaSyncSqlPlan, SelectedSchemaDiffInput, GenerateSchemaSyncPlanOptions, TableDiff, FunctionDiff, SequenceDiff, RuleDiff, OwnerDiff } from "@/lib/schema/schemaDiff";
|
||||
@@ -1827,6 +1828,10 @@ export async function buildDataGridContextFilterCondition(options: DataGridConte
|
||||
return result ?? undefined;
|
||||
}
|
||||
|
||||
export async function buildDmlChangePreviewSql(options: DmlChangePreviewSqlOptions): Promise<DmlChangePreviewSqlResult> {
|
||||
return invoke("build_dml_change_preview_sql", { options });
|
||||
}
|
||||
|
||||
export async function buildDataGridColumnValueFilterCondition(options: DataGridColumnValueFilterConditionOptions): Promise<string | undefined> {
|
||||
const result = await invoke<string | null>("build_data_grid_column_value_filter_condition", { options });
|
||||
return result ?? undefined;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { looksLikeDmlStatement } from "../dmlChangePreview";
|
||||
|
||||
describe("looksLikeDmlStatement", () => {
|
||||
it("recognizes UPDATE / INSERT / DELETE statements", () => {
|
||||
expect(looksLikeDmlStatement("UPDATE admin_sessions SET public_id = 123 WHERE id = 1")).toBe(true);
|
||||
expect(looksLikeDmlStatement(" INSERT INTO t (a) VALUES (1)")).toBe(true);
|
||||
expect(looksLikeDmlStatement("\nDELETE FROM t WHERE id = 2")).toBe(true);
|
||||
});
|
||||
it("ignores leading whitespace and preserves case-insensitivity", () => {
|
||||
expect(looksLikeDmlStatement(" update t set a = 1")).toBe(true);
|
||||
expect(looksLikeDmlStatement("Insert into t values (1)")).toBe(true);
|
||||
});
|
||||
it("rejects non-DML and unrelated statements", () => {
|
||||
expect(looksLikeDmlStatement("SELECT * FROM t")).toBe(false);
|
||||
expect(looksLikeDmlStatement("WITH x AS (SELECT 1) SELECT * FROM x")).toBe(false);
|
||||
expect(looksLikeDmlStatement("")).toBe(false);
|
||||
expect(looksLikeDmlStatement("CREATE TABLE t (a int)")).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
/** 「预览变更」请求/响应的前端类型(对应后端 dml_preview_sql)。 */
|
||||
|
||||
export interface DmlChangePreviewSqlOptions {
|
||||
/** 用户写的一条 DML 语句(通常是当前语句)。 */
|
||||
sql: string;
|
||||
/** 连接类型(决定解析方言 / 默认标识符引号)。 */
|
||||
databaseType?: string;
|
||||
/** 连接的标识符引号字符(如 `"`、`` ` ``、`[`)。 */
|
||||
identifierQuote?: string;
|
||||
/** 目标表的列(ordinal)。提供且为单表 UPDATE 时,新值列紧跟其原值列。 */
|
||||
columns?: string[];
|
||||
}
|
||||
|
||||
export interface DmlChangePreviewTableRef {
|
||||
catalog?: string;
|
||||
database?: string;
|
||||
schema?: string;
|
||||
table?: string;
|
||||
}
|
||||
|
||||
export interface DmlChangePreviewSqlResult {
|
||||
/** 生成的只读 SELECT:在结果网格展示受影响行 + 「新值」列。 */
|
||||
sql: string;
|
||||
/** 语句类型:update / insert / delete。 */
|
||||
operation: string;
|
||||
/** 是否有「新值」列(仅 UPDATE 有)。 */
|
||||
hasNewValueColumns: boolean;
|
||||
/** 语句目标表引用(供前端拉取列元数据以交错展示新值列)。 */
|
||||
tables: DmlChangePreviewTableRef[];
|
||||
}
|
||||
|
||||
/** 从 SQL 文本粗略识别是否为可预览的 DML(用于「预览变更」入口显隐)。 */
|
||||
const DML_PREVIEW_RE = /^\s*(update|insert|delete)\b/i;
|
||||
|
||||
export function looksLikeDmlStatement(sql: string): boolean {
|
||||
return DML_PREVIEW_RE.test(sql);
|
||||
}
|
||||
Reference in new issue
Block a user