mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-29 16:18:55 +00:00
fix: handle MySQL backup SQL import
This commit is contained in:
@@ -88,6 +88,7 @@ import {
|
||||
} from "@/lib/databaseCapabilities";
|
||||
import { sidebarSelectionCopyAction, treeNodeRowAction, treeNodeRowDoubleClickAction } from "@/lib/treeNodeClick";
|
||||
import { formatCsv, formatJson, formatSqlInsert } from "@/lib/exportFormats";
|
||||
import { buildCreateDatabaseSql, supportsCreateDatabaseCharset } from "@/lib/createDatabaseSql";
|
||||
import { hexToRgba } from "@/lib/color";
|
||||
import DangerConfirmDialog from "@/components/editor/DangerConfirmDialog.vue";
|
||||
import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
@@ -604,6 +605,8 @@ const duplicateTableName = ref("");
|
||||
|
||||
const showCreateDatabaseDialog = ref(false);
|
||||
const createDatabaseName = ref("");
|
||||
const createDatabaseCharset = ref("utf8mb4");
|
||||
const createDatabaseCollation = ref("utf8mb4_unicode_ci");
|
||||
const showDropDatabaseConfirm = ref(false);
|
||||
const showCreateSchemaDialog = ref(false);
|
||||
const createSchemaName = ref("");
|
||||
@@ -682,6 +685,11 @@ const canCreateDatabase = computed(() => {
|
||||
return props.node.type === "connection" && supportsDatabaseCreation(config?.db_type);
|
||||
});
|
||||
|
||||
const canSetCreateDatabaseCharset = computed(() => {
|
||||
const config = props.node.connectionId ? connectionStore.getConfig(props.node.connectionId) : undefined;
|
||||
return supportsCreateDatabaseCharset(config?.db_type, config?.driver_profile);
|
||||
});
|
||||
|
||||
const canDropDatabase = computed(() => {
|
||||
const config = props.node.connectionId ? connectionStore.getConfig(props.node.connectionId) : undefined;
|
||||
return props.node.type === "database" && supportsDatabaseCreation(config?.db_type);
|
||||
@@ -786,6 +794,8 @@ function buildDropSchemaSql(): string {
|
||||
|
||||
function openCreateDatabaseDialog() {
|
||||
createDatabaseName.value = "";
|
||||
createDatabaseCharset.value = "utf8mb4";
|
||||
createDatabaseCollation.value = "utf8mb4_unicode_ci";
|
||||
showCreateDatabaseDialog.value = true;
|
||||
}
|
||||
|
||||
@@ -796,7 +806,14 @@ async function confirmCreateDatabase() {
|
||||
showCreateDatabaseDialog.value = false;
|
||||
try {
|
||||
await connectionStore.ensureConnected(node.connectionId);
|
||||
const sql = `CREATE DATABASE ${quoteIdent(name)};`;
|
||||
const config = connectionStore.getConfig(node.connectionId);
|
||||
const sql = buildCreateDatabaseSql({
|
||||
databaseType: config?.db_type,
|
||||
driverProfile: config?.driver_profile,
|
||||
name,
|
||||
charset: createDatabaseCharset.value,
|
||||
collation: createDatabaseCollation.value,
|
||||
});
|
||||
await api.executeQuery(node.connectionId, "", sql);
|
||||
toast(t("contextMenu.createDatabaseSuccess", { name }), 3000);
|
||||
await connectionStore.loadDatabases(node.connectionId, { force: true });
|
||||
@@ -2037,6 +2054,26 @@ const isDragging = computed(() => dragState.active && dragState.draggedId === pr
|
||||
:placeholder="t('contextMenu.createDatabaseNamePlaceholder')"
|
||||
@keydown.enter.prevent="confirmCreateDatabase"
|
||||
/>
|
||||
<div v-if="canSetCreateDatabaseCharset" class="grid gap-2">
|
||||
<div class="grid gap-1.5">
|
||||
<label class="text-xs font-medium text-muted-foreground">{{ t("contextMenu.createDatabaseCharset") }}</label>
|
||||
<Input
|
||||
v-model="createDatabaseCharset"
|
||||
:placeholder="t('contextMenu.createDatabaseCharsetPlaceholder')"
|
||||
@keydown.enter.prevent="confirmCreateDatabase"
|
||||
/>
|
||||
</div>
|
||||
<div class="grid gap-1.5">
|
||||
<label class="text-xs font-medium text-muted-foreground">{{
|
||||
t("contextMenu.createDatabaseCollation")
|
||||
}}</label>
|
||||
<Input
|
||||
v-model="createDatabaseCollation"
|
||||
:placeholder="t('contextMenu.createDatabaseCollationPlaceholder')"
|
||||
@keydown.enter.prevent="confirmCreateDatabase"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" @click="showCreateDatabaseDialog = false">{{ t("dangerDialog.cancel") }}</Button>
|
||||
<Button :disabled="!createDatabaseName.trim()" @click="confirmCreateDatabase">{{
|
||||
|
||||
@@ -660,6 +660,10 @@ export default {
|
||||
createDatabaseSuccess: 'Database "{name}" created',
|
||||
dropDatabaseSuccess: 'Database "{name}" dropped',
|
||||
createDatabaseNamePlaceholder: "Database name",
|
||||
createDatabaseCharset: "Character set",
|
||||
createDatabaseCharsetPlaceholder: "e.g. utf8mb4",
|
||||
createDatabaseCollation: "Collation",
|
||||
createDatabaseCollationPlaceholder: "e.g. utf8mb4_unicode_ci",
|
||||
createSchema: "Create Schema",
|
||||
dropSchema: "Drop Schema",
|
||||
confirmDropSchemaTitle: "Drop Schema",
|
||||
|
||||
@@ -643,6 +643,10 @@ export default {
|
||||
createDatabaseSuccess: "数据库「{name}」已创建",
|
||||
dropDatabaseSuccess: "数据库「{name}」已删除",
|
||||
createDatabaseNamePlaceholder: "数据库名称",
|
||||
createDatabaseCharset: "字符集",
|
||||
createDatabaseCharsetPlaceholder: "例如 utf8mb4",
|
||||
createDatabaseCollation: "排序规则",
|
||||
createDatabaseCollationPlaceholder: "例如 utf8mb4_unicode_ci",
|
||||
createSchema: "新建 Schema",
|
||||
dropSchema: "删除 Schema",
|
||||
confirmDropSchemaTitle: "删除 Schema",
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { DatabaseType } from "@/types/database";
|
||||
import { quoteTableIdentifier } from "./tableSelectSql";
|
||||
|
||||
const MYSQL_COMPATIBLE_PROFILES = new Set([
|
||||
"mysql",
|
||||
"mariadb",
|
||||
"tidb",
|
||||
"oceanbase",
|
||||
"doris",
|
||||
"starrocks",
|
||||
"custom_mysql",
|
||||
]);
|
||||
const MYSQL_COMPATIBLE_TYPES = new Set<DatabaseType>(["mysql", "doris", "starrocks", "goldendb"]);
|
||||
|
||||
export interface CreateDatabaseSqlOptions {
|
||||
databaseType?: DatabaseType;
|
||||
driverProfile?: string | null;
|
||||
name: string;
|
||||
charset?: string;
|
||||
collation?: string;
|
||||
}
|
||||
|
||||
export function supportsCreateDatabaseCharset(databaseType?: DatabaseType, driverProfile?: string | null): boolean {
|
||||
return (
|
||||
MYSQL_COMPATIBLE_TYPES.has(databaseType as DatabaseType) ||
|
||||
(!!driverProfile && MYSQL_COMPATIBLE_PROFILES.has(driverProfile))
|
||||
);
|
||||
}
|
||||
|
||||
export function buildCreateDatabaseSql(options: CreateDatabaseSqlOptions): string {
|
||||
const name = quoteTableIdentifier(options.databaseType, options.name);
|
||||
const charset = cleanSqlOption(options.charset);
|
||||
const collation = cleanSqlOption(options.collation);
|
||||
if (!supportsCreateDatabaseCharset(options.databaseType, options.driverProfile) || !charset) {
|
||||
return `CREATE DATABASE ${name};`;
|
||||
}
|
||||
const collateClause = collation ? ` COLLATE ${collation}` : "";
|
||||
return `CREATE DATABASE ${name} CHARACTER SET ${charset}${collateClause};`;
|
||||
}
|
||||
|
||||
function cleanSqlOption(value: string | undefined): string {
|
||||
return value?.trim().replace(/[;\s]+/g, "") ?? "";
|
||||
}
|
||||
Reference in New Issue
Block a user