fix(postgres): preserve copied table comments safely
This commit is contained in:
10 files changed
+166
-19
No files matched your search
@@ -71,6 +71,7 @@ import {
|
||||
buildEmptyTableSql,
|
||||
buildTruncateTableSql,
|
||||
collectDuplicateTableColumnComments,
|
||||
duplicateTableStructureRequiresScript,
|
||||
supportsDropTableCascade,
|
||||
supportsTruncateTableCascade,
|
||||
type TableAdminSqlOptions,
|
||||
@@ -241,7 +242,7 @@ const batchEmptyPlan = ref<BatchTableEmptyPlanItem<ObjectBrowserRow>[]>([]);
|
||||
// Paste table dialog state
|
||||
const showPasteDialog = ref(false);
|
||||
const pasteTableMode = ref<PasteTableMode>("structure-and-data");
|
||||
const pasteTableEntries = ref<{ sourceName: string; targetName: string; schema?: string }[]>([]);
|
||||
const pasteTableEntries = ref<{ sourceName: string; targetName: string; schema?: string; tableComment?: string | null }[]>([]);
|
||||
const pasteTableDataCopySupported = computed(() => supportsWholeRowTableDataCopy(effectiveDatabaseType.value));
|
||||
const objectColumnWidths = ref<Record<ObjectBrowserColumnKey, number>>({
|
||||
select: 34,
|
||||
@@ -1910,7 +1911,7 @@ function requestDuplicateStructure(row: ObjectBrowserRow) {
|
||||
showDuplicateDialog.value = true;
|
||||
}
|
||||
|
||||
async function buildDuplicateStructurePlan(sourceName: string, targetName: string, schema: string | undefined, sourceColumns?: ColumnInfo[]) {
|
||||
async function buildDuplicateStructurePlan(sourceName: string, targetName: string, schema: string | undefined, tableComment?: string | null, sourceColumns?: ColumnInfo[]) {
|
||||
let columns = sourceColumns;
|
||||
if (effectiveDatabaseType.value === "dameng" && !columns) {
|
||||
try {
|
||||
@@ -1925,9 +1926,10 @@ async function buildDuplicateStructurePlan(sourceName: string, targetName: strin
|
||||
schema,
|
||||
sourceName,
|
||||
targetName,
|
||||
tableComment,
|
||||
columnComments,
|
||||
});
|
||||
return { sql, sourceColumns: columns, executeAsScript: columnComments.length > 0 };
|
||||
return { sql, sourceColumns: columns, executeAsScript: duplicateTableStructureRequiresScript(sql) };
|
||||
}
|
||||
|
||||
function executeDuplicateStructurePlan(plan: { sql: string; executeAsScript: boolean }, schema: string | undefined) {
|
||||
@@ -1941,7 +1943,7 @@ async function confirmDuplicateStructure() {
|
||||
showDuplicateDialog.value = false;
|
||||
try {
|
||||
const schema = row.schema || selectedSchema.value;
|
||||
const plan = await buildDuplicateStructurePlan(row.name, newName, schema);
|
||||
const plan = await buildDuplicateStructurePlan(row.name, newName, schema, row.comment);
|
||||
const executed = await executeObjectBrowserSqlWithProductionGuard(plan.sql, () => executeDuplicateStructurePlan(plan, schema));
|
||||
if (!executed) return;
|
||||
toast(t("contextMenu.duplicateStructureSuccess", { name: newName }));
|
||||
@@ -1962,6 +1964,7 @@ function copySelectedTablesToClipboard() {
|
||||
database: props.database,
|
||||
schema: normalizeObjectBrowserTableClipboardSchema(row.schema || selectedSchema.value),
|
||||
tableName: row.name,
|
||||
tableComment: row.comment,
|
||||
})),
|
||||
};
|
||||
toast(t("contextMenu.pasteTableClipboardUpdated"), 2000);
|
||||
@@ -2031,6 +2034,7 @@ function copySingleTableToClipboard(row: ObjectBrowserRow) {
|
||||
database: props.database,
|
||||
schema: normalizeObjectBrowserTableClipboardSchema(row.schema || selectedSchema.value),
|
||||
tableName: row.name,
|
||||
tableComment: row.comment,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -2052,6 +2056,7 @@ function openPasteTableDialog() {
|
||||
sourceName: entry.tableName,
|
||||
targetName: `${entry.tableName}_copy`,
|
||||
schema: normalizeObjectBrowserTableClipboardSchema(entry.schema, entry.database, entry.connectionId),
|
||||
tableComment: entry.tableComment,
|
||||
}));
|
||||
showPasteDialog.value = true;
|
||||
}
|
||||
@@ -2090,7 +2095,7 @@ async function confirmPasteTable() {
|
||||
try {
|
||||
let sourceColumns: ColumnInfo[] | undefined;
|
||||
if (mode === "structure-and-data" || mode === "structure-only") {
|
||||
const plan = await buildDuplicateStructurePlan(entry.sourceName, targetName, schema, sourceColumns);
|
||||
const plan = await buildDuplicateStructurePlan(entry.sourceName, targetName, schema, entry.tableComment, sourceColumns);
|
||||
sourceColumns = plan.sourceColumns;
|
||||
const executed = await executeObjectBrowserSqlWithProductionGuard(plan.sql, () => executeDuplicateStructurePlan(plan, schema));
|
||||
if (!executed) {
|
||||
|
||||
@@ -30,4 +30,10 @@ describe("ObjectBrowser table clipboard context menu", () => {
|
||||
expect(objectBrowserSource).toMatch(/if \(!executed\) \{[\s\S]*?pasteCancelled = true;[\s\S]*?break;/);
|
||||
expect(objectBrowserSource).toMatch(/if \(pasteCancelled\) \{[\s\S]*?if \(hasMutatedTable\)[\s\S]*?await reload\(\)[\s\S]*?refreshObjectListTreeNode[\s\S]*?pasteTableCancelledAfterPartial[\s\S]*?return;/);
|
||||
});
|
||||
|
||||
it("carries table comments through local copy and paste", () => {
|
||||
expect(objectBrowserSource).toMatch(/tableName: row\.name,\s*tableComment: row\.comment/);
|
||||
expect(objectBrowserSource).toMatch(/targetName: `\$\{entry\.tableName\}_copy`,[\s\S]*?tableComment: entry\.tableComment/);
|
||||
expect(objectBrowserSource).toMatch(/buildDuplicateStructurePlan\(entry\.sourceName, targetName, schema, entry\.tableComment/);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user