feat(gbase8s): read create-database locale options from the instance
This commit is contained in:
3 files changed
+50
-4
No files matched your search
@@ -202,7 +202,7 @@ import { savedSqlClipboardFileIds, savedSqlPasteTargetForNode } from "@/lib/save
|
||||
import { exportSavedSqlFileContent } from "@/lib/savedSql/savedSqlExport";
|
||||
import { isSqlServerLinkedNode } from "@/lib/database/sqlServerLinkedServers";
|
||||
import { flattenTree } from "@/composables/useFlatTree";
|
||||
import { createDatabaseCollationOptionsForCharset, DEFAULT_GBASE8S_DATABASE_LOCALE, GBASE8S_DATABASE_LOCALES, nextCreateDatabaseCollation, normalizeCreateDatabaseCharset, parseCreateDatabaseCharsetMetadata } from "@/lib/database/createDatabaseCharsetOptions";
|
||||
import { createDatabaseCollationOptionsForCharset, DEFAULT_GBASE8S_DATABASE_LOCALE, defaultGbase8sDatabaseLocale, GBASE8S_DATABASE_LOCALES, nextCreateDatabaseCollation, normalizeCreateDatabaseCharset, parseCreateDatabaseCharsetMetadata } from "@/lib/database/createDatabaseCharsetOptions";
|
||||
import { executeWithProductionContextGuard, executeWithProductionSqlGuard } from "@/lib/database/productionExecutionGuard";
|
||||
import { connectionIsEffectivelyReadOnly } from "@/lib/database/readOnlyWriteAccess";
|
||||
import { buildXuguCompileSql } from "@/lib/database/xuguCompileSql";
|
||||
@@ -3828,12 +3828,13 @@ function openCreateDatabaseDialog() {
|
||||
showCreateDatabaseDialog.value = true;
|
||||
if (canSetCreateDatabaseLocale.value) {
|
||||
// GBase 8s / Informix: the "charset" control selects the new database's DB_LOCALE, which the
|
||||
// agent applies by opening the CREATE DATABASE session with it. Default to UTF-8 so new
|
||||
// databases can store Chinese; no server charset catalog query is needed.
|
||||
// agent applies by opening the CREATE DATABASE session with it. Seed a UTF-8 default, then
|
||||
// repopulate the options with the collations already present on the connected instance.
|
||||
createDatabaseCharsetOptions.value = [...GBASE8S_DATABASE_LOCALES];
|
||||
createDatabaseCollationsByCharset.value = {};
|
||||
createDatabaseCharset.value = DEFAULT_GBASE8S_DATABASE_LOCALE;
|
||||
createDatabaseCollation.value = "";
|
||||
void loadGbase8sDatabaseLocales();
|
||||
} else if (canSetCreateDatabaseCharset.value) {
|
||||
void loadCreateDatabaseCharsetMetadata();
|
||||
}
|
||||
@@ -3958,6 +3959,33 @@ async function loadCreateDatabaseCharsetMetadata(target: "create" | "edit" = "cr
|
||||
}
|
||||
}
|
||||
|
||||
async function loadGbase8sDatabaseLocales() {
|
||||
const node = activeNode.value;
|
||||
if (!node.connectionId) return;
|
||||
createDatabaseCharsetLoading.value = true;
|
||||
try {
|
||||
await connectionStore.ensureConnected(node.connectionId);
|
||||
const result = await api.executeQuery(node.connectionId, "", "SELECT DISTINCT dbs_collate FROM sysmaster:sysdbslocale ORDER BY 1", undefined, undefined, { maxRows: 500 });
|
||||
if (!showCreateDatabaseDialog.value) return;
|
||||
const idx = result.columns.findIndex((column) => column.trim().toLowerCase() === "dbs_collate");
|
||||
const locales = [...new Set(result.rows.map((row) => String(row[idx >= 0 ? idx : 0] ?? "").trim()).filter(Boolean))];
|
||||
if (!locales.length) throw new Error("no collations");
|
||||
createDatabaseCharsetOptions.value = locales;
|
||||
createDatabaseCollationsByCharset.value = {};
|
||||
if (!locales.includes(createDatabaseCharset.value)) {
|
||||
updateCreateDatabaseCharset(defaultGbase8sDatabaseLocale(locales));
|
||||
}
|
||||
} catch {
|
||||
createDatabaseCharsetOptions.value = [...GBASE8S_DATABASE_LOCALES];
|
||||
createDatabaseCollationsByCharset.value = {};
|
||||
if (!createDatabaseCharsetOptions.value.includes(createDatabaseCharset.value)) {
|
||||
updateCreateDatabaseCharset(DEFAULT_GBASE8S_DATABASE_LOCALE);
|
||||
}
|
||||
} finally {
|
||||
createDatabaseCharsetLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function ensureDuckDbFileExtension(path: string): string {
|
||||
return /\.(duckdb|db)$/i.test(path) ? path : `${path}.duckdb`;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { supportsCreateDatabaseCharset, supportsCreateDatabaseLocale } from "@/lib/database/createDatabaseSql";
|
||||
import { DEFAULT_GBASE8S_DATABASE_LOCALE, GBASE8S_DATABASE_LOCALES } from "@/lib/database/createDatabaseCharsetOptions";
|
||||
import { DEFAULT_GBASE8S_DATABASE_LOCALE, defaultGbase8sDatabaseLocale, GBASE8S_DATABASE_LOCALES } from "@/lib/database/createDatabaseCharsetOptions";
|
||||
|
||||
describe("GBase 8s / Informix create-database locale support", () => {
|
||||
it("offers a locale picker only for the gbase8s profile", () => {
|
||||
@@ -22,4 +22,16 @@ describe("GBase 8s / Informix create-database locale support", () => {
|
||||
expect(GBASE8S_DATABASE_LOCALES).toContain("zh_CN.utf8");
|
||||
expect(DEFAULT_GBASE8S_DATABASE_LOCALE).toBe("zh_CN.utf8");
|
||||
});
|
||||
|
||||
it("seeds the default from instance locales reporting the numeric UTF-8 code set", () => {
|
||||
// Real GBase 8s instances report dbs_collate like zh_CN.57372 (57372 = UTF-8) alongside
|
||||
// en_US.819 (ISO-8859-1); after ORDER BY 1 the plain first entry cannot hold CJK.
|
||||
expect(defaultGbase8sDatabaseLocale(["en_US.819", "zh_CN.57372"])).toBe("zh_CN.57372");
|
||||
expect(defaultGbase8sDatabaseLocale(["en_US.819", "zh_CN.utf8"])).toBe("zh_CN.utf8");
|
||||
});
|
||||
|
||||
it("falls back to the first locale or the static default when no UTF-8 option exists", () => {
|
||||
expect(defaultGbase8sDatabaseLocale(["en_US.819"])).toBe("en_US.819");
|
||||
expect(defaultGbase8sDatabaseLocale([])).toBe(DEFAULT_GBASE8S_DATABASE_LOCALE);
|
||||
});
|
||||
});
|
||||
@@ -16,6 +16,12 @@ export const CREATE_DATABASE_CHARSET_OPTIONS = ["utf8mb4", "utf8", "gbk", "latin
|
||||
export const GBASE8S_DATABASE_LOCALES = ["zh_CN.utf8", "en_US.utf8", "ja_JP.utf8", "ko_KR.utf8", "zh_CN.gbk", "zh_CN.gb18030", "en_US.819"] as const;
|
||||
export const DEFAULT_GBASE8S_DATABASE_LOCALE = "zh_CN.utf8";
|
||||
|
||||
// Informix-family instances report dbs_collate with the numeric code set (57372 = UTF-8,
|
||||
// 819 = ISO-8859-1) instead of the "utf8" mnemonic, so both spellings must seed the default.
|
||||
export function defaultGbase8sDatabaseLocale(locales: string[]): string {
|
||||
return locales.find((locale) => /(?:utf8|57372)/i.test(locale)) ?? locales[0] ?? DEFAULT_GBASE8S_DATABASE_LOCALE;
|
||||
}
|
||||
|
||||
const FALLBACK_COLLATION_OPTIONS: Record<string, string[]> = {
|
||||
ascii: ["ascii_general_ci", "ascii_bin"],
|
||||
big5: ["big5_chinese_ci", "big5_bin"],
|
||||
|
||||
Reference in new issue
Block a user