feat(schema-diff): support case-insensitive table and column matching
This commit is contained in:
1 parent
0ef8369e2b
commit
3123e962c8
23 files changed
+726
-94
No files matched your search
@@ -83,17 +83,17 @@ const restrictTables = ref(false);
|
||||
const localSelectedTables = ref<string[]>([]);
|
||||
|
||||
const activeTableMappings = computed(() => props.options?.tableMappings ?? []);
|
||||
const tableMatches = computed<SchemaDiffTableMatch[]>(() => buildSchemaDiffTableMatches(localSelectedTables.value, targetTableList.value, activeTableMappings.value));
|
||||
const tableMatches = computed<SchemaDiffTableMatch[]>(() => buildSchemaDiffTableMatches(localSelectedTables.value, targetTableList.value, activeTableMappings.value, props.options.ignoreTableNameCase));
|
||||
const matchedTableCount = computed(() => tableMatches.value.filter((match) => match.targetTable).length);
|
||||
const missingTargetTables = computed(() => tableMatches.value.filter((match) => !match.targetTable).map((match) => match.sourceTable));
|
||||
const tableMappingConflictSource = ref<string | null>(null);
|
||||
|
||||
function targetTableOptions(sourceTable: string): string[] {
|
||||
return availableSchemaDiffTargetTables(sourceTable, targetTableList.value, activeTableMappings.value);
|
||||
return availableSchemaDiffTargetTables(sourceTable, targetTableList.value, activeTableMappings.value, props.options.ignoreTableNameCase);
|
||||
}
|
||||
|
||||
function handleTableMappingUpdate(sourceTable: string, targetTable: string) {
|
||||
const update = updateSchemaDiffTableMapping(activeTableMappings.value, sourceTable, targetTable);
|
||||
const update = updateSchemaDiffTableMapping(activeTableMappings.value, sourceTable, targetTable, props.options.ignoreTableNameCase);
|
||||
if (update.accepted) {
|
||||
tableMappingConflictSource.value = null;
|
||||
emitTableMappings(update.mappings);
|
||||
@@ -107,7 +107,7 @@ function emitTableMappings(nextMappings: SchemaDiffTableMapping[]) {
|
||||
}
|
||||
|
||||
function reconcileTableMappings(selectedTables: string[], targetTables = targetTableList.value) {
|
||||
const nextMappings = targetTableListLoaded.value ? reconcileSchemaDiffTableMappings(selectedTables, targetTables, activeTableMappings.value) : pruneSchemaDiffTableMappings(selectedTables, activeTableMappings.value);
|
||||
const nextMappings = targetTableListLoaded.value ? reconcileSchemaDiffTableMappings(selectedTables, targetTables, activeTableMappings.value, props.options.ignoreTableNameCase) : pruneSchemaDiffTableMappings(selectedTables, activeTableMappings.value);
|
||||
emitTableMappings(nextMappings);
|
||||
}
|
||||
|
||||
|
||||
@@ -591,6 +591,8 @@ async function handleCompare() {
|
||||
ignoreComments: ignoreComments.value,
|
||||
cascadeDelete: opts?.cascadeDelete ?? false,
|
||||
compareColumnOrder: opts.compareColumnOrder,
|
||||
ignoreTableNameCase: opts.ignoreTableNameCase,
|
||||
ignoreColumnNameCase: opts.ignoreColumnNameCase,
|
||||
detectRenames: opts?.detectRenames ?? false,
|
||||
detectTableRenames: opts?.detectTableRenames ?? false,
|
||||
renameThreshold: opts?.renameThreshold ?? 0.5,
|
||||
|
||||
@@ -112,6 +112,8 @@ describe("SchemaDiffDialog fullscreen layout", () => {
|
||||
expect(configStepSource).toContain("tableMatchStatus.${match.kind}");
|
||||
expect(dialogSource).toContain('@update:table-mappings="handleTableMappingsUpdate"');
|
||||
expect(dialogSource).toContain("tableMappings: opts.selectedTables === undefined ? undefined : opts.tableMappings");
|
||||
expect(dialogSource).toContain("ignoreTableNameCase: opts.ignoreTableNameCase");
|
||||
expect(dialogSource).toContain("ignoreColumnNameCase: opts.ignoreColumnNameCase");
|
||||
expect(dialogSource).toContain("const swappedMappings = swapSchemaDiffTableMappings(currentOptions.tableMappings ?? []);");
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
import { createApp, defineComponent, h, nextTick, ref, type App } from "vue";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { DEFAULT_POSTGRES_OPTIONS, type SchemaDiffCompareOptions, type SchemaDiffOptionItem } from "@/types/schemaDiff";
|
||||
import { getSchemaDiffOptionsForDbType } from "@/lib/schema/schemaDiffOptions";
|
||||
import { DEFAULT_POSTGRES_OPTIONS, normalizeSchemaDiffCompareOptions, type SchemaDiffCompareOptions, type SchemaDiffOptionItem } from "@/types/schemaDiff";
|
||||
|
||||
vi.mock("vue-i18n", () => ({ useI18n: () => ({ t: (key: string) => key }) }));
|
||||
|
||||
@@ -49,6 +50,14 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("SchemaDiffOptionsPanel", () => {
|
||||
it("exposes independent case-insensitive name options with false defaults", () => {
|
||||
const ids = getSchemaDiffOptionsForDbType("postgres").map((item) => item.id);
|
||||
expect(ids).toEqual(expect.arrayContaining(["ignoreTableNameCase", "ignoreColumnNameCase"]));
|
||||
const normalized = normalizeSchemaDiffCompareOptions({});
|
||||
expect(normalized.ignoreTableNameCase).toBe(false);
|
||||
expect(normalized.ignoreColumnNameCase).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps unsaved checkbox edits when the parent refreshes equivalent options", async () => {
|
||||
const options = ref<SchemaDiffCompareOptions>({ ...DEFAULT_POSTGRES_OPTIONS });
|
||||
const optionTree: SchemaDiffOptionItem[] = [{ id: "views", labelKey: "views", defaultChecked: true }];
|
||||
|
||||
Reference in new issue
Block a user