fix(schema-diff): qualify MySQL deploy SQL target
This commit is contained in:
parent
9a730ce188
commit
0c2d95b83e
|
|
@ -19,7 +19,7 @@ import { createConcurrencyLimiter, mapWithConcurrency, schemaDiffMetadataConcurr
|
|||
import { normalizeSchemaDiffCompareOptions } from "@/types/schemaDiff";
|
||||
import type { SchemaDiffCompareOptions, SchemaDiffConfig } from "@/types/schemaDiff";
|
||||
import type { ObjectSourceKind, TableInfo } from "@/types/database";
|
||||
import { buildDeploySqlForObjects, convertToSchemaDiffObjects, groupDiffObjects, type OperationGroup, type SchemaDiffObject, type DiffOperationType, type DiffObjectKind, type SchemaDiffPreparation, type TableSchemaDetail } from "@/lib/schemaDiff";
|
||||
import { buildDeploySqlForObjects, convertToSchemaDiffObjects, groupDiffObjects, schemaDiffDeployTargetSchema, type OperationGroup, type SchemaDiffObject, type DiffOperationType, type DiffObjectKind, type SchemaDiffPreparation, type TableSchemaDetail } from "@/lib/schemaDiff";
|
||||
import { compileSchemaDiffTableFilter, filterSchemaDiffTables } from "@/lib/schemaDiffTableFilter";
|
||||
import { Splitpanes, Pane } from "splitpanes";
|
||||
import "splitpanes/dist/splitpanes.css";
|
||||
|
|
@ -390,7 +390,7 @@ async function handleCompare() {
|
|||
sourceOwners: srcOwners,
|
||||
targetOwners: tgtOwners,
|
||||
databaseType: dbType,
|
||||
targetSchema: targetSchema.value,
|
||||
targetSchema: schemaDiffDeployTargetSchema(dbType, targetDatabase.value, targetSchema.value),
|
||||
ignoreComments: ignoreComments.value,
|
||||
cascadeDelete: opts?.cascadeDelete ?? false,
|
||||
compareColumnOrder: opts.compareColumnOrder,
|
||||
|
|
|
|||
|
|
@ -117,6 +117,20 @@ export interface SchemaDiffPreparation {
|
|||
syncSql: string;
|
||||
}
|
||||
|
||||
const MYSQL_LIKE_SCHEMA_DIFF_TARGET_TYPES = new Set<DatabaseType>(["mysql", "doris", "starrocks", "goldendb", "sundb", "databend", "gbase"]);
|
||||
|
||||
export function schemaDiffDeployTargetSchema(databaseType: DatabaseType | undefined, targetDatabase: string, targetSchema?: string): string | undefined {
|
||||
const schema = targetSchema?.trim();
|
||||
if (schema) return schema;
|
||||
|
||||
const database = targetDatabase.trim();
|
||||
if (databaseType && MYSQL_LIKE_SCHEMA_DIFF_TARGET_TYPES.has(databaseType) && database) {
|
||||
return database;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Unified object type for UI display
|
||||
export type DiffOperationType = "modify" | "create" | "delete" | "none";
|
||||
export type DiffObjectKind = "table" | "view" | "function" | "sequence" | "rule" | "owner" | "index" | "trigger" | "foreignKey";
|
||||
|
|
|
|||
|
|
@ -957,6 +957,8 @@ fn column_def(col: &ColumnInfo, db_type: DatabaseType) -> String {
|
|||
|
||||
fn qualified_name(name: &str, db_type: DatabaseType, schema: Option<&str>) -> String {
|
||||
schema
|
||||
.map(str::trim)
|
||||
.filter(|schema| !schema.is_empty())
|
||||
.map(|schema| format!("{}.{}", quote_id(schema, db_type), quote_id(name, db_type)))
|
||||
.unwrap_or_else(|| quote_id(name, db_type))
|
||||
}
|
||||
|
|
@ -1660,6 +1662,69 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_schema_sync_sql_qualifies_tables_with_target_database() {
|
||||
let diffs = vec![TableDiff {
|
||||
diff_type: "modified".to_string(),
|
||||
object_type: None,
|
||||
name: "notify_channel_config".to_string(),
|
||||
columns: Some(vec![ColumnDiff {
|
||||
diff_type: "modified".to_string(),
|
||||
name: "config_json".to_string(),
|
||||
source: Some(column("config_json", "json", Some("渠道配置"))),
|
||||
target: Some(column("config_json", "json", Some("Config"))),
|
||||
changes: vec!["comment: Config → 渠道配置".to_string()],
|
||||
}]),
|
||||
indexes: None,
|
||||
foreign_keys: None,
|
||||
triggers: None,
|
||||
ddl: None,
|
||||
target_ddl: None,
|
||||
source_table_comment: None,
|
||||
target_table_comment: None,
|
||||
sync_sql: None,
|
||||
}];
|
||||
|
||||
assert_eq!(
|
||||
generate_schema_sync_sql(&diffs, &[], &[], &[], &[], DatabaseType::Mysql, Some("target_db"), false),
|
||||
[
|
||||
"-- Alter table: notify_channel_config",
|
||||
"ALTER TABLE `target_db`.`notify_channel_config`",
|
||||
" MODIFY COLUMN `config_json` json NOT NULL COMMENT '渠道配置';",
|
||||
]
|
||||
.join("\n")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blank_target_schema_does_not_generate_empty_qualifier() {
|
||||
let diffs = vec![TableDiff {
|
||||
diff_type: "modified".to_string(),
|
||||
object_type: None,
|
||||
name: "notify_channel_config".to_string(),
|
||||
columns: Some(vec![ColumnDiff {
|
||||
diff_type: "modified".to_string(),
|
||||
name: "config_json".to_string(),
|
||||
source: Some(column("config_json", "json", Some("渠道配置"))),
|
||||
target: Some(column("config_json", "json", Some("Config"))),
|
||||
changes: vec!["comment: Config → 渠道配置".to_string()],
|
||||
}]),
|
||||
indexes: None,
|
||||
foreign_keys: None,
|
||||
triggers: None,
|
||||
ddl: None,
|
||||
target_ddl: None,
|
||||
source_table_comment: None,
|
||||
target_table_comment: None,
|
||||
sync_sql: None,
|
||||
}];
|
||||
|
||||
let sql = generate_schema_sync_sql(&diffs, &[], &[], &[], &[], DatabaseType::Mysql, Some(" "), false);
|
||||
|
||||
assert!(sql.contains("ALTER TABLE `notify_channel_config`"));
|
||||
assert!(!sql.contains("``."));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_comments_skips_column_and_table_comment_diffs() {
|
||||
let options = SchemaDiffPreparationOptions {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { test } from "vitest";
|
||||
import { buildDeploySqlForObjects, convertToSchemaDiffObjects, type TableDiff } from "../../apps/desktop/src/lib/schemaDiff.ts";
|
||||
import { buildDeploySqlForObjects, convertToSchemaDiffObjects, schemaDiffDeployTargetSchema, type TableDiff } from "../../apps/desktop/src/lib/schemaDiff.ts";
|
||||
|
||||
test("uses generated sync SQL for modified table deployment", () => {
|
||||
const tableDiffs: TableDiff[] = [
|
||||
|
|
@ -44,3 +44,10 @@ test("falls back to source DDL when object sync SQL is unavailable", () => {
|
|||
|
||||
assert.equal(buildDeploySqlForObjects(objects), "-- Create table: users\nCREATE TABLE `users` (`id` int);\n");
|
||||
});
|
||||
|
||||
test("uses mysql target database as schema diff deploy qualifier", () => {
|
||||
assert.equal(schemaDiffDeployTargetSchema("mysql", "target_db", ""), "target_db");
|
||||
assert.equal(schemaDiffDeployTargetSchema("mysql", "target_db", " "), "target_db");
|
||||
assert.equal(schemaDiffDeployTargetSchema("mysql", "target_db", "explicit_schema"), "explicit_schema");
|
||||
assert.equal(schemaDiffDeployTargetSchema("sqlite", "main", ""), undefined);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue