需要在顶部导航栏「驱动管理」中安装对应的驱动才能连接。
diff --git a/src/components/diagram/SchemaDiagramDialog.vue b/src/components/diagram/SchemaDiagramDialog.vue
index 4354060155..f4343ba67b 100644
--- a/src/components/diagram/SchemaDiagramDialog.vue
+++ b/src/components/diagram/SchemaDiagramDialog.vue
@@ -9,7 +9,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
import { useConnectionStore } from "@/stores/connectionStore";
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
import * as api from "@/lib/api";
-import { DIAGRAM_SQL_TYPES, SCHEMA_AWARE_TYPES } from "@/lib/databaseCapabilities";
+import { DIAGRAM_SQL_TYPES, isSchemaAware as isSchemaAwareDatabase } from "@/lib/databaseCapabilities";
import {
buildDiagramRelationships,
filterDiagramTables,
@@ -91,9 +91,7 @@ const sqlConnections = computed(() =>
const selectedConnection = computed(() => (connectionId.value ? store.getConfig(connectionId.value) : undefined));
-const isSchemaAware = computed(
- () => !!selectedConnection.value && SCHEMA_AWARE_TYPES.has(selectedConnection.value.db_type),
-);
+const isSchemaAware = computed(() => isSchemaAwareDatabase(selectedConnection.value?.db_type));
const allRelationships = computed(() => buildDiagramRelationships(tables.value));
diff --git a/src/components/search/DatabaseSearchDialog.vue b/src/components/search/DatabaseSearchDialog.vue
index 4155ca7220..53fe634496 100644
--- a/src/components/search/DatabaseSearchDialog.vue
+++ b/src/components/search/DatabaseSearchDialog.vue
@@ -12,7 +12,7 @@ import { useConnectionStore } from "@/stores/connectionStore";
import * as api from "@/lib/api";
import { buildDatabaseSearchSql, buildSearchResultWhere, findMatchedSearchColumns } from "@/lib/databaseSearch";
import type { DatabaseType, TableInfo } from "@/types/database";
-import { SCHEMA_AWARE_TYPES } from "@/lib/databaseCapabilities";
+import { isSchemaAware } from "@/lib/databaseCapabilities";
const props = defineProps<{
open: boolean;
@@ -116,10 +116,6 @@ function resetSearchState() {
currentExecutionId.value = "";
}
-function isSchemaAware(databaseType?: DatabaseType): boolean {
- return !!databaseType && SCHEMA_AWARE_TYPES.has(databaseType);
-}
-
function isSearchableTable(table: TableInfo): boolean {
const type = table.table_type.toUpperCase();
return type.includes("TABLE") && !type.includes("VIEW");
diff --git a/src/components/transfer/DataTransferDialog.vue b/src/components/transfer/DataTransferDialog.vue
index f994af7099..f66cbec21e 100644
--- a/src/components/transfer/DataTransferDialog.vue
+++ b/src/components/transfer/DataTransferDialog.vue
@@ -12,7 +12,7 @@ import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
import * as api from "@/lib/api";
import type { TransferProgress, TransferMode } from "@/lib/api";
import type { DatabaseType } from "@/types/database";
-import { TRANSFER_SQL_TYPES, isSchemaAware } from "@/lib/databaseCapabilities";
+import { isSchemaAware, supportsTransfer } from "@/lib/databaseCapabilities";
import { nextTransferTerminalState } from "@/lib/transferProgressState";
import { ArrowRightLeft, Check, X, Loader2, Square, CheckSquare } from "lucide-vue-next";
@@ -26,7 +26,7 @@ const props = defineProps<{
const store = useConnectionStore();
-const sqlConnections = computed(() => store.connections.filter((c) => TRANSFER_SQL_TYPES.has(c.db_type)));
+const sqlConnections = computed(() => store.connections.filter((c) => supportsTransfer(c.db_type)));
// Source state
const sourceConnectionId = ref("");
diff --git a/src/lib/databaseCapabilities.ts b/src/lib/databaseCapabilities.ts
index 5c06d09349..9b4e979dae 100644
--- a/src/lib/databaseCapabilities.ts
+++ b/src/lib/databaseCapabilities.ts
@@ -1,178 +1,3 @@
-import type { DatabaseType } from "@/types/database";
-
-export const SCHEMA_AWARE_TYPES = new Set([
- "postgres",
- "sqlserver",
- "oracle",
- "redshift",
- "dameng",
- "gaussdb",
- "kingbase",
- "vastbase",
- "jdbc",
- "h2",
- "snowflake",
- "trino",
- "db2",
- "informix",
-]);
-
-export const SQL_FILE_UNSUPPORTED_TYPES = new Set(["redis", "mongodb", "elasticsearch"]);
-
-export const DIAGRAM_SUPPORTED_TYPES = new Set([
- "mysql",
- "postgres",
- "sqlite",
- "sqlserver",
- "oracle",
- "redshift",
- "dameng",
- "gaussdb",
- "kingbase",
- "vastbase",
- "goldendb",
- "h2",
- "db2",
-]);
-
-export const DATABASE_SEARCH_SUPPORTED_TYPES = new Set([
- "mysql",
- "postgres",
- "sqlite",
- "sqlserver",
- "oracle",
- "redshift",
- "duckdb",
- "clickhouse",
- "dameng",
- "gaussdb",
- "kingbase",
- "vastbase",
- "goldendb",
- "h2",
- "snowflake",
- "trino",
- "hive",
- "db2",
- "informix",
- "neo4j",
- "cassandra",
- "bigquery",
- "kylin",
- "sundb",
-]);
-
-export const TABLE_IMPORT_SUPPORTED_TYPES = new Set([
- "mysql",
- "postgres",
- "sqlite",
- "duckdb",
- "clickhouse",
- "sqlserver",
- "oracle",
- "doris",
- "starrocks",
- "redshift",
- "dameng",
- "gaussdb",
- "kingbase",
- "vastbase",
- "goldendb",
-]);
-
-export const TABLE_STRUCTURE_SUPPORTED_TYPES = new Set(["mysql", "postgres", "sqlite", "sqlserver"]);
-
-export const CREATE_DATABASE_SUPPORTED_TYPES = new Set([
- "mysql",
- "postgres",
- "sqlserver",
- "clickhouse",
- "oracle",
- "dameng",
- "gaussdb",
- "doris",
- "starrocks",
- "redshift",
-]);
-
-export const FIELD_LINEAGE_SUPPORTED_TYPES = new Set([
- "mysql",
- "postgres",
- "sqlite",
- "sqlserver",
- "oracle",
- "redshift",
- "dameng",
- "gaussdb",
-]);
-
-export const SINGLE_DATABASE_TYPES = new Set(["oracle", "dameng"]);
-
-export const FETCH_FIRST_TYPES = new Set(["oracle", "dameng"]);
-
-export const TREE_SCHEMA_TYPES = new Set([
- "postgres",
- "redshift",
- "sqlserver",
- "gaussdb",
- "jdbc",
- "trino",
- "h2",
-]);
-
-export const PG_LIKE_STRUCTURE_TYPES = new Set(["postgres", "redshift", "gaussdb"]);
-
-export const AGENT_DRIVER_TYPES = new Set([
- "dameng",
- "kingbase",
- "vastbase",
- "goldendb",
- "oracle",
- "h2",
- "snowflake",
- "trino",
- "hive",
- "db2",
- "informix",
- "neo4j",
- "cassandra",
- "bigquery",
- "kylin",
- "sundb",
- "gaussdb",
-]);
-
-export const TRANSFER_SQL_TYPES = new Set([
- "mysql",
- "postgres",
- "sqlite",
- "sqlserver",
- "oracle",
- "clickhouse",
- "duckdb",
- "dameng",
- "gaussdb",
-]);
-
-export const DIAGRAM_SQL_TYPES = new Set([
- "mysql",
- "postgres",
- "sqlite",
- "sqlserver",
- "oracle",
- "redshift",
- "dameng",
- "gaussdb",
-]);
-
-export function isSchemaAware(dbType?: DatabaseType): boolean {
- return !!dbType && SCHEMA_AWARE_TYPES.has(dbType);
-}
-
-export function isSingleDatabase(dbType?: DatabaseType): boolean {
- return !!dbType && SINGLE_DATABASE_TYPES.has(dbType);
-}
-
-export function usesFetchFirst(dbType?: DatabaseType): boolean {
- return !!dbType && FETCH_FIRST_TYPES.has(dbType);
-}
+export * from "./databaseCapabilitySets";
+export * from "./databaseFeatureSupport";
+export * from "./databaseTableDataCapabilities";
diff --git a/src/lib/databaseCapabilitySets.ts b/src/lib/databaseCapabilitySets.ts
new file mode 100644
index 0000000000..3e77c5749b
--- /dev/null
+++ b/src/lib/databaseCapabilitySets.ts
@@ -0,0 +1,166 @@
+import type { DatabaseType } from "@/types/database";
+
+export const SCHEMA_AWARE_TYPES = new Set([
+ "postgres",
+ "sqlserver",
+ "oracle",
+ "redshift",
+ "dameng",
+ "gaussdb",
+ "kingbase",
+ "vastbase",
+ "jdbc",
+ "h2",
+ "snowflake",
+ "trino",
+ "db2",
+ "informix",
+]);
+
+export const SQL_FILE_UNSUPPORTED_TYPES = new Set(["redis", "mongodb", "elasticsearch"]);
+
+export const DIAGRAM_SUPPORTED_TYPES = new Set([
+ "mysql",
+ "postgres",
+ "sqlite",
+ "sqlserver",
+ "oracle",
+ "redshift",
+ "dameng",
+ "gaussdb",
+ "kingbase",
+ "vastbase",
+ "goldendb",
+ "h2",
+ "db2",
+]);
+
+export const DATABASE_SEARCH_SUPPORTED_TYPES = new Set([
+ "mysql",
+ "postgres",
+ "sqlite",
+ "sqlserver",
+ "oracle",
+ "redshift",
+ "duckdb",
+ "clickhouse",
+ "dameng",
+ "gaussdb",
+ "kingbase",
+ "vastbase",
+ "goldendb",
+ "h2",
+ "snowflake",
+ "trino",
+ "hive",
+ "db2",
+ "informix",
+ "neo4j",
+ "cassandra",
+ "bigquery",
+ "kylin",
+ "sundb",
+]);
+
+export const TABLE_IMPORT_SUPPORTED_TYPES = new Set([
+ "mysql",
+ "postgres",
+ "sqlite",
+ "duckdb",
+ "clickhouse",
+ "sqlserver",
+ "oracle",
+ "doris",
+ "starrocks",
+ "redshift",
+ "dameng",
+ "gaussdb",
+ "kingbase",
+ "vastbase",
+ "goldendb",
+]);
+
+export const TABLE_STRUCTURE_SUPPORTED_TYPES = new Set(["mysql", "postgres", "sqlite", "sqlserver"]);
+
+export const CREATE_DATABASE_SUPPORTED_TYPES = new Set([
+ "mysql",
+ "postgres",
+ "sqlserver",
+ "clickhouse",
+ "oracle",
+ "dameng",
+ "gaussdb",
+ "doris",
+ "starrocks",
+ "redshift",
+]);
+
+export const FIELD_LINEAGE_SUPPORTED_TYPES = new Set([
+ "mysql",
+ "postgres",
+ "sqlite",
+ "sqlserver",
+ "oracle",
+ "redshift",
+ "dameng",
+ "gaussdb",
+]);
+
+export const SINGLE_DATABASE_TYPES = new Set(["oracle", "dameng"]);
+
+export const FETCH_FIRST_TYPES = new Set(["oracle", "dameng"]);
+
+export const TREE_SCHEMA_TYPES = new Set([
+ "postgres",
+ "redshift",
+ "sqlserver",
+ "gaussdb",
+ "jdbc",
+ "trino",
+ "h2",
+]);
+
+export const PG_LIKE_STRUCTURE_TYPES = new Set(["postgres", "redshift", "gaussdb"]);
+
+export const AGENT_DRIVER_TYPES = new Set([
+ "dameng",
+ "kingbase",
+ "vastbase",
+ "goldendb",
+ "oracle",
+ "h2",
+ "snowflake",
+ "trino",
+ "hive",
+ "db2",
+ "informix",
+ "neo4j",
+ "cassandra",
+ "bigquery",
+ "kylin",
+ "sundb",
+ "gaussdb",
+]);
+
+export const TRANSFER_SQL_TYPES = new Set([
+ "mysql",
+ "postgres",
+ "sqlite",
+ "sqlserver",
+ "oracle",
+ "clickhouse",
+ "duckdb",
+ "dameng",
+ "gaussdb",
+]);
+
+export const DIAGRAM_SQL_TYPES = new Set([
+ "mysql",
+ "postgres",
+ "sqlite",
+ "sqlserver",
+ "oracle",
+ "redshift",
+ "dameng",
+ "gaussdb",
+]);
diff --git a/src/lib/databaseFeatureSupport.ts b/src/lib/databaseFeatureSupport.ts
new file mode 100644
index 0000000000..a49557bd69
--- /dev/null
+++ b/src/lib/databaseFeatureSupport.ts
@@ -0,0 +1,81 @@
+import type { DatabaseType } from "@/types/database";
+import {
+ AGENT_DRIVER_TYPES,
+ CREATE_DATABASE_SUPPORTED_TYPES,
+ DATABASE_SEARCH_SUPPORTED_TYPES,
+ DIAGRAM_SUPPORTED_TYPES,
+ FETCH_FIRST_TYPES,
+ FIELD_LINEAGE_SUPPORTED_TYPES,
+ PG_LIKE_STRUCTURE_TYPES,
+ SCHEMA_AWARE_TYPES,
+ SINGLE_DATABASE_TYPES,
+ SQL_FILE_UNSUPPORTED_TYPES,
+ TABLE_IMPORT_SUPPORTED_TYPES,
+ TABLE_STRUCTURE_SUPPORTED_TYPES,
+ TRANSFER_SQL_TYPES,
+ TREE_SCHEMA_TYPES,
+} from "./databaseCapabilitySets";
+
+export function isSchemaAware(dbType?: DatabaseType): boolean {
+ return !!dbType && SCHEMA_AWARE_TYPES.has(dbType);
+}
+
+export function usesTreeSchemaMode(dbType?: DatabaseType): boolean {
+ return !!dbType && TREE_SCHEMA_TYPES.has(dbType);
+}
+
+export function isSingleDatabase(dbType?: DatabaseType): boolean {
+ return !!dbType && SINGLE_DATABASE_TYPES.has(dbType);
+}
+
+export function usesFetchFirst(dbType?: DatabaseType): boolean {
+ return !!dbType && FETCH_FIRST_TYPES.has(dbType);
+}
+
+export function supportsSqlFileExecution(dbType?: DatabaseType): boolean {
+ return !!dbType && !SQL_FILE_UNSUPPORTED_TYPES.has(dbType);
+}
+
+export function supportsSchemaDiagram(dbType?: DatabaseType): boolean {
+ return !!dbType && DIAGRAM_SUPPORTED_TYPES.has(dbType);
+}
+
+export function supportsDatabaseSearch(dbType?: DatabaseType): boolean {
+ return !!dbType && DATABASE_SEARCH_SUPPORTED_TYPES.has(dbType);
+}
+
+export function supportsTableImport(dbType?: DatabaseType): boolean {
+ return !!dbType && TABLE_IMPORT_SUPPORTED_TYPES.has(dbType);
+}
+
+export function supportsTableStructureEditing(dbType?: DatabaseType): boolean {
+ return !!dbType && TABLE_STRUCTURE_SUPPORTED_TYPES.has(dbType);
+}
+
+export function supportsDatabaseCreation(dbType?: DatabaseType): boolean {
+ return !!dbType && CREATE_DATABASE_SUPPORTED_TYPES.has(dbType);
+}
+
+export function supportsFieldLineage(dbType?: DatabaseType): boolean {
+ return !!dbType && FIELD_LINEAGE_SUPPORTED_TYPES.has(dbType);
+}
+
+export function supportsTransfer(dbType?: DatabaseType): boolean {
+ return !!dbType && TRANSFER_SQL_TYPES.has(dbType);
+}
+
+export function supportsDriverManagement(dbType?: DatabaseType): boolean {
+ return !!dbType && AGENT_DRIVER_TYPES.has(dbType);
+}
+
+export function supportsObjectBrowser(dbType?: DatabaseType): boolean {
+ return !!dbType && !["redis", "mongodb", "elasticsearch"].includes(dbType);
+}
+
+export function supportsTableTruncate(dbType?: DatabaseType): boolean {
+ return !!dbType && dbType !== "sqlite" && dbType !== "duckdb";
+}
+
+export function usesPostgresLikeStructureCopy(dbType?: DatabaseType): boolean {
+ return !!dbType && PG_LIKE_STRUCTURE_TYPES.has(dbType);
+}
diff --git a/src/lib/databaseTableDataCapabilities.ts b/src/lib/databaseTableDataCapabilities.ts
new file mode 100644
index 0000000000..ec22ec2aca
--- /dev/null
+++ b/src/lib/databaseTableDataCapabilities.ts
@@ -0,0 +1,74 @@
+import type { DatabaseType } from "@/types/database";
+import { isSchemaAware, usesTreeSchemaMode } from "./databaseFeatureSupport";
+
+export type SyntheticEditKey = "oracle-rowid" | "neo4j-element-id";
+
+export interface TableDataCapability {
+ insert: boolean;
+ updateRequiresPrimaryKey: boolean;
+ deleteRequiresPrimaryKey: boolean;
+ requiresTransactionalTableForExistingRows: boolean;
+ transaction: boolean;
+}
+
+export interface DatabaseCapability {
+ schemaAware: boolean;
+ treeSchemaMode: boolean;
+ tableData: TableDataCapability;
+ syntheticKey?: SyntheticEditKey;
+}
+
+const DEFAULT_TABLE_DATA_CAPABILITY: TableDataCapability = {
+ insert: false,
+ updateRequiresPrimaryKey: true,
+ deleteRequiresPrimaryKey: true,
+ requiresTransactionalTableForExistingRows: false,
+ transaction: true,
+};
+
+const DEFAULT_CAPABILITY: DatabaseCapability = {
+ schemaAware: false,
+ treeSchemaMode: false,
+ tableData: DEFAULT_TABLE_DATA_CAPABILITY,
+};
+
+const DATABASE_CAPABILITY_OVERRIDES: Partial>> = {
+ hive: {
+ tableData: {
+ insert: true,
+ updateRequiresPrimaryKey: false,
+ deleteRequiresPrimaryKey: false,
+ requiresTransactionalTableForExistingRows: true,
+ transaction: false,
+ },
+ },
+ neo4j: {
+ syntheticKey: "neo4j-element-id",
+ },
+ oracle: {
+ syntheticKey: "oracle-rowid",
+ },
+ trino: {
+ tableData: {
+ insert: true,
+ updateRequiresPrimaryKey: true,
+ deleteRequiresPrimaryKey: true,
+ requiresTransactionalTableForExistingRows: false,
+ transaction: false,
+ },
+ },
+};
+
+export function getDatabaseCapability(dbType?: DatabaseType): DatabaseCapability {
+ const override = dbType ? DATABASE_CAPABILITY_OVERRIDES[dbType] : undefined;
+ return {
+ ...DEFAULT_CAPABILITY,
+ ...override,
+ schemaAware: isSchemaAware(dbType),
+ treeSchemaMode: usesTreeSchemaMode(dbType),
+ tableData: {
+ ...DEFAULT_TABLE_DATA_CAPABILITY,
+ ...override?.tableData,
+ },
+ };
+}
diff --git a/src/lib/tableEditing.ts b/src/lib/tableEditing.ts
index 7ea66a8884..6efd3425eb 100644
--- a/src/lib/tableEditing.ts
+++ b/src/lib/tableEditing.ts
@@ -1,32 +1,34 @@
import type { ColumnInfo, DatabaseType } from "@/types/database";
+import { getDatabaseCapability } from "./databaseCapabilities";
export const DBX_ROWID_COLUMN = "__DBX_ROWID";
export const DBX_NEO4J_ELEMENT_ID_COLUMN = "__DBX_ELEMENT_ID";
export function editablePrimaryKeys(databaseType: DatabaseType | undefined, columns: ColumnInfo[]): string[] {
const primaryKeys = columns.filter((column) => column.is_primary_key).map((column) => column.name);
- if (databaseType === "oracle" && primaryKeys.length === 0) return [DBX_ROWID_COLUMN];
- if (databaseType === "neo4j" && primaryKeys.length === 0) return [DBX_NEO4J_ELEMENT_ID_COLUMN];
+ const syntheticKey = getDatabaseCapability(databaseType).syntheticKey;
+ if (syntheticKey === "oracle-rowid" && primaryKeys.length === 0) return [DBX_ROWID_COLUMN];
+ if (syntheticKey === "neo4j-element-id" && primaryKeys.length === 0) return [DBX_NEO4J_ELEMENT_ID_COLUMN];
return primaryKeys;
}
export function isTableDataEditable(databaseType: DatabaseType | undefined, primaryKeys: string[]): boolean {
- if (databaseType === "hive") return true;
- if (databaseType === "trino") return true;
+ if (getDatabaseCapability(databaseType).tableData.insert) return true;
return primaryKeys.length > 0;
}
export function supportsDataGridTransaction(databaseType: DatabaseType | undefined): boolean {
- return databaseType !== "hive" && databaseType !== "trino";
+ return getDatabaseCapability(databaseType).tableData.transaction;
}
export function canEditExistingTableRows(
databaseType: DatabaseType | undefined,
hiveTableTransactional?: boolean,
- primaryKeys: string[] = [],
+ primaryKeys?: string[],
): boolean {
- if (databaseType === "hive") return hiveTableTransactional === true;
- if (databaseType === "trino") return primaryKeys.length > 0;
+ const tableData = getDatabaseCapability(databaseType).tableData;
+ if (tableData.requiresTransactionalTableForExistingRows && hiveTableTransactional !== true) return false;
+ if (tableData.updateRequiresPrimaryKey && primaryKeys && primaryKeys.length === 0) return false;
return true;
}
diff --git a/src/stores/connectionStore.ts b/src/stores/connectionStore.ts
index dd7116c50d..bfece434b4 100644
--- a/src/stores/connectionStore.ts
+++ b/src/stores/connectionStore.ts
@@ -20,7 +20,7 @@ import {
import type { SqlCompletionColumn, SqlCompletionTable } from "@/lib/sqlCompletion";
import * as api from "@/lib/api";
import { isTauriRuntime } from "@/lib/tauriRuntime";
-import { isSchemaAware, TREE_SCHEMA_TYPES } from "@/lib/databaseCapabilities";
+import { isSchemaAware, usesTreeSchemaMode } from "@/lib/databaseCapabilities";
import { buildDatabaseTreeNodes } from "@/lib/databaseTree";
import { buildSqlServerDatabaseTreeNodes, SQLSERVER_DEFAULT_SCHEMA } from "@/lib/sqlServerTree";
import {
@@ -932,7 +932,7 @@ export const useConnectionStore = defineStore("connection", () => {
const config = getConfig(node.connectionId);
if (config?.db_type === "sqlserver") {
await loadSqlServerDatabaseObjects(node.connectionId, node.database, options);
- } else if (config?.db_type && TREE_SCHEMA_TYPES.has(config.db_type)) {
+ } else if (usesTreeSchemaMode(config?.db_type)) {
await loadSchemas(node.connectionId, node.database, options);
} else {
await loadTables(node.connectionId, node.database, undefined, options);
diff --git a/tests/databaseCapabilities.test.ts b/tests/databaseCapabilities.test.ts
index 46d06bda2b..c683377461 100644
--- a/tests/databaseCapabilities.test.ts
+++ b/tests/databaseCapabilities.test.ts
@@ -1,11 +1,100 @@
import assert from "node:assert/strict";
import test from "node:test";
-import { SCHEMA_AWARE_TYPES, TREE_SCHEMA_TYPES } from "../src/lib/databaseCapabilities.ts";
+import {
+ SCHEMA_AWARE_TYPES,
+ TREE_SCHEMA_TYPES,
+ getDatabaseCapability,
+ supportsDatabaseCreation,
+ supportsDatabaseSearch,
+ supportsDriverManagement,
+ supportsFieldLineage,
+ supportsObjectBrowser,
+ supportsSchemaDiagram,
+ supportsSqlFileExecution,
+ supportsTableImport,
+ supportsTableTruncate,
+ supportsTableStructureEditing,
+ supportsTransfer,
+ usesPostgresLikeStructureCopy,
+ usesTreeSchemaMode,
+} from "../src/lib/databaseCapabilities.ts";
test("treats Trino catalogs as schema tree roots", () => {
assert.equal(TREE_SCHEMA_TYPES.has("trino"), true);
});
+test("describes schema tree mode through the capability helper", () => {
+ assert.equal(usesTreeSchemaMode("trino"), true);
+ assert.equal(usesTreeSchemaMode("h2"), true);
+ assert.equal(usesTreeSchemaMode("mysql"), false);
+ assert.equal(usesTreeSchemaMode(undefined), false);
+});
+
test("treats Trino tables as schema-qualified SQL targets", () => {
assert.equal(SCHEMA_AWARE_TYPES.has("trino"), true);
});
+
+test("describes table editing capabilities for special database engines", () => {
+ assert.deepEqual(getDatabaseCapability("hive").tableData, {
+ insert: true,
+ updateRequiresPrimaryKey: false,
+ deleteRequiresPrimaryKey: false,
+ requiresTransactionalTableForExistingRows: true,
+ transaction: false,
+ });
+
+ assert.deepEqual(getDatabaseCapability("trino").tableData, {
+ insert: true,
+ updateRequiresPrimaryKey: true,
+ deleteRequiresPrimaryKey: true,
+ requiresTransactionalTableForExistingRows: false,
+ transaction: false,
+ });
+
+ assert.equal(getDatabaseCapability("oracle").syntheticKey, "oracle-rowid");
+ assert.equal(getDatabaseCapability("neo4j").syntheticKey, "neo4j-element-id");
+});
+
+test("uses conservative table editing defaults for unknown or keyless relational engines", () => {
+ assert.deepEqual(getDatabaseCapability("postgres").tableData, {
+ insert: false,
+ updateRequiresPrimaryKey: true,
+ deleteRequiresPrimaryKey: true,
+ requiresTransactionalTableForExistingRows: false,
+ transaction: true,
+ });
+ assert.deepEqual(getDatabaseCapability(undefined).tableData, {
+ insert: false,
+ updateRequiresPrimaryKey: true,
+ deleteRequiresPrimaryKey: true,
+ requiresTransactionalTableForExistingRows: false,
+ transaction: true,
+ });
+});
+
+test("describes feature support through capability helpers", () => {
+ assert.equal(supportsSqlFileExecution("mysql"), true);
+ assert.equal(supportsSqlFileExecution("redis"), false);
+ assert.equal(supportsSchemaDiagram("oracle"), true);
+ assert.equal(supportsSchemaDiagram("trino"), false);
+ assert.equal(supportsDatabaseSearch("neo4j"), true);
+ assert.equal(supportsDatabaseSearch("redis"), false);
+ assert.equal(supportsTableImport("duckdb"), true);
+ assert.equal(supportsTableImport("hive"), false);
+ assert.equal(supportsTableStructureEditing("postgres"), true);
+ assert.equal(supportsTableStructureEditing("oracle"), false);
+ assert.equal(supportsDatabaseCreation("clickhouse"), true);
+ assert.equal(supportsDatabaseCreation("sqlite"), false);
+ assert.equal(supportsFieldLineage("gaussdb"), true);
+ assert.equal(supportsFieldLineage("trino"), false);
+ assert.equal(supportsTransfer("duckdb"), true);
+ assert.equal(supportsTransfer("hive"), false);
+ assert.equal(supportsDriverManagement("oracle"), true);
+ assert.equal(supportsDriverManagement("mysql"), false);
+ assert.equal(usesPostgresLikeStructureCopy("gaussdb"), true);
+ assert.equal(usesPostgresLikeStructureCopy("mysql"), false);
+ assert.equal(supportsObjectBrowser("mysql"), true);
+ assert.equal(supportsObjectBrowser("mongodb"), false);
+ assert.equal(supportsTableTruncate("mysql"), true);
+ assert.equal(supportsTableTruncate("duckdb"), false);
+});