refactor: centralize database type groups into databaseCapabilities.ts
Extract all inline database type checks (schema-aware, pagination style, feature support sets, etc.) into a single source of truth. Adding a new database type now requires updating only one file instead of 15+.
This commit is contained in:
parent
fde76d5576
commit
629bd02b0f
|
|
@ -33,6 +33,7 @@ import { resolveExecutableSql } from "@/lib/sqlExecutionTarget";
|
|||
import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
import { isCloseTabShortcut, isExecuteSqlShortcut } from "@/lib/keyboardShortcuts";
|
||||
import { isPreviewTab } from "@/lib/tabPresentation";
|
||||
import { SQL_FILE_UNSUPPORTED_TYPES } from "@/lib/databaseCapabilities";
|
||||
|
||||
const { t } = useI18n();
|
||||
const connectionStore = useConnectionStore();
|
||||
|
|
@ -103,9 +104,8 @@ const { onExecuteSql, onReloadData, onPaginate, onSort } = useDataGridActions(ac
|
|||
const { setupTauriListeners } = useTauriEvents({ openTableTarget });
|
||||
|
||||
const appVersion = ref("");
|
||||
const sqlFileUnsupportedTypes = new Set(["redis", "mongodb", "elasticsearch"]);
|
||||
const hasSqlFileConnections = computed(() =>
|
||||
connectionStore.connections.some((c) => !sqlFileUnsupportedTypes.has(c.db_type)),
|
||||
connectionStore.connections.some((c) => !SQL_FILE_UNSUPPORTED_TYPES.has(c.db_type)),
|
||||
);
|
||||
const connectionStats = computed(() => ({
|
||||
total: connectionStore.connections.length,
|
||||
|
|
|
|||
|
|
@ -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 type { DatabaseType } from "@/types/database";
|
||||
import { DIAGRAM_SQL_TYPES, SCHEMA_AWARE_TYPES } from "@/lib/databaseCapabilities";
|
||||
import {
|
||||
buildDiagramRelationships,
|
||||
filterDiagramTables,
|
||||
|
|
@ -49,17 +49,6 @@ const props = defineProps<{
|
|||
focusTableName?: string;
|
||||
}>();
|
||||
|
||||
const SQL_TYPES: DatabaseType[] = [
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
];
|
||||
const SCHEMA_AWARE_TYPES: DatabaseType[] = ["postgres", "sqlserver", "oracle", "redshift", "dameng", "gaussdb"];
|
||||
const CARD_WIDTH = 270;
|
||||
const COLUMN_ROW_HEIGHT = 24;
|
||||
const CARD_HEADER_HEIGHT = 44;
|
||||
|
|
@ -96,12 +85,14 @@ const dragging = ref<{
|
|||
originY: number;
|
||||
} | null>(null);
|
||||
|
||||
const sqlConnections = computed(() => store.connections.filter((connection) => SQL_TYPES.includes(connection.db_type)));
|
||||
const sqlConnections = computed(() =>
|
||||
store.connections.filter((connection) => DIAGRAM_SQL_TYPES.has(connection.db_type)),
|
||||
);
|
||||
|
||||
const selectedConnection = computed(() => (connectionId.value ? store.getConfig(connectionId.value) : undefined));
|
||||
|
||||
const isSchemaAware = computed(
|
||||
() => !!selectedConnection.value && SCHEMA_AWARE_TYPES.includes(selectedConnection.value.db_type),
|
||||
() => !!selectedConnection.value && SCHEMA_AWARE_TYPES.has(selectedConnection.value.db_type),
|
||||
);
|
||||
|
||||
const allRelationships = computed(() => buildDiagramRelationships(tables.value));
|
||||
|
|
|
|||
|
|
@ -9,6 +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 { isSchemaAware } from "@/lib/databaseCapabilities";
|
||||
import { diffColumns, diffIndexes, diffTables, generateSyncSql, type TableDiff } from "@/lib/schemaDiff";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { Loader2, Copy, Play, GitCompareArrows } from "lucide-vue-next";
|
||||
|
|
@ -72,13 +73,7 @@ async function loadDatabases(connectionId: string, side: "source" | "target") {
|
|||
|
||||
async function resolveSchema(connectionId: string, database: string): Promise<string> {
|
||||
const config = store.getConfig(connectionId);
|
||||
const needsSchema =
|
||||
config?.db_type === "postgres" ||
|
||||
config?.db_type === "sqlserver" ||
|
||||
config?.db_type === "oracle" ||
|
||||
config?.db_type === "redshift" ||
|
||||
config?.db_type === "dameng" ||
|
||||
config?.db_type === "gaussdb";
|
||||
const needsSchema = isSchemaAware(config?.db_type);
|
||||
if (needsSchema) {
|
||||
const schemas = await api.listSchemas(connectionId, database);
|
||||
return schemas.includes("public") ? "public" : (schemas[0] ?? "");
|
||||
|
|
|
|||
|
|
@ -12,6 +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";
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean;
|
||||
|
|
@ -54,7 +55,6 @@ type SearchTableTask = {
|
|||
table: TableInfo;
|
||||
};
|
||||
|
||||
const SCHEMA_AWARE_TYPES = new Set<DatabaseType>(["postgres", "sqlserver", "oracle", "redshift", "dameng", "gaussdb"]);
|
||||
const SYSTEM_SCHEMAS = new Set([
|
||||
"information_schema",
|
||||
"pg_catalog",
|
||||
|
|
|
|||
|
|
@ -61,6 +61,18 @@ import {
|
|||
type ExportedTableSql,
|
||||
} from "@/lib/databaseExport";
|
||||
import { qualifiedTableName as buildQualifiedTableName, quoteTableIdentifier } from "@/lib/tableSelectSql";
|
||||
import {
|
||||
SQL_FILE_UNSUPPORTED_TYPES,
|
||||
DIAGRAM_SUPPORTED_TYPES,
|
||||
DATABASE_SEARCH_SUPPORTED_TYPES,
|
||||
TABLE_IMPORT_SUPPORTED_TYPES,
|
||||
TABLE_STRUCTURE_SUPPORTED_TYPES,
|
||||
FIELD_LINEAGE_SUPPORTED_TYPES,
|
||||
TREE_SCHEMA_TYPES,
|
||||
PG_LIKE_STRUCTURE_TYPES,
|
||||
isSchemaAware,
|
||||
usesFetchFirst,
|
||||
} from "@/lib/databaseCapabilities";
|
||||
import { treeNodeRowAction } from "@/lib/treeNodeClick";
|
||||
import DangerConfirmDialog from "@/components/editor/DangerConfirmDialog.vue";
|
||||
import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
|
|
@ -86,54 +98,6 @@ const emit = defineEmits<{
|
|||
"rename-started": [];
|
||||
}>();
|
||||
|
||||
const sqlFileUnsupportedTypes = new Set(["redis", "mongodb", "elasticsearch"]);
|
||||
const diagramSupportedTypes = new Set([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
const databaseSearchSupportedTypes = new Set([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"duckdb",
|
||||
"clickhouse",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
const tableImportSupportedTypes = new Set([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"duckdb",
|
||||
"clickhouse",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"doris",
|
||||
"starrocks",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
const tableStructureSupportedTypes = new Set(["mysql", "postgres", "sqlite", "sqlserver"]);
|
||||
const fieldLineageSupportedTypes = new Set([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
const isExportingDatabase = ref(false);
|
||||
|
||||
function currentDatabaseType(): DatabaseType | undefined {
|
||||
|
|
@ -144,16 +108,6 @@ function quoteIdent(name: string): string {
|
|||
return quoteTableIdentifier(currentDatabaseType(), name);
|
||||
}
|
||||
|
||||
function isSchemaAwareDbType(dbType?: DatabaseType): boolean {
|
||||
return (
|
||||
dbType === "postgres" ||
|
||||
dbType === "oracle" ||
|
||||
dbType === "sqlserver" ||
|
||||
dbType === "dameng" ||
|
||||
dbType === "gaussdb"
|
||||
);
|
||||
}
|
||||
|
||||
function qualifiedTableName(tableName: string, schema?: string): string {
|
||||
return buildQualifiedTableName({
|
||||
databaseType: currentDatabaseType(),
|
||||
|
|
@ -260,7 +214,7 @@ async function toggle() {
|
|||
queryStore.updateSql(tab, node.label);
|
||||
} else if (node.type === "database" && node.connectionId && node.database) {
|
||||
const config = connectionStore.getConfig(node.connectionId);
|
||||
if (config?.db_type === "postgres" || config?.db_type === "sqlserver" || config?.db_type === "gaussdb") {
|
||||
if (config?.db_type && TREE_SCHEMA_TYPES.has(config.db_type)) {
|
||||
await connectionStore.loadSchemas(node.connectionId, node.database);
|
||||
} else {
|
||||
await connectionStore.loadTables(node.connectionId, node.database);
|
||||
|
|
@ -305,11 +259,7 @@ async function openData() {
|
|||
if (!config) throw new Error("Connection config not found");
|
||||
|
||||
const qualifiedName =
|
||||
(config.db_type === "postgres" ||
|
||||
config.db_type === "oracle" ||
|
||||
config.db_type === "sqlserver" ||
|
||||
config.db_type === "dameng") &&
|
||||
node.schema
|
||||
isSchemaAware(config.db_type) && node.schema
|
||||
? `${quoteIdent(node.schema)}.${quoteIdent(node.label)}`
|
||||
: quoteIdent(node.label);
|
||||
|
||||
|
|
@ -318,7 +268,7 @@ async function openData() {
|
|||
const pks = columns.filter((c) => c.is_primary_key).map((c) => c.name);
|
||||
const order = pks.length ? ` ORDER BY ${pks.map((pk) => `${quoteIdent(pk)} ASC`).join(", ")}` : "";
|
||||
let sql: string;
|
||||
if (config.db_type === "oracle" || config.db_type === "dameng") {
|
||||
if (usesFetchFirst(config.db_type)) {
|
||||
sql = `SELECT * FROM ${qualifiedName}${order} FETCH FIRST 100 ROWS ONLY`;
|
||||
} else if (config.db_type === "sqlserver") {
|
||||
sql = `SELECT TOP 100 * FROM ${qualifiedName}${order}`;
|
||||
|
|
@ -400,7 +350,7 @@ const canCreateTable = computed(() => {
|
|||
(props.node.type === "database" || props.node.type === "schema") &&
|
||||
!!props.node.database &&
|
||||
!!config &&
|
||||
tableStructureSupportedTypes.has(config.db_type)
|
||||
TABLE_STRUCTURE_SUPPORTED_TYPES.has(config.db_type)
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -490,11 +440,11 @@ async function confirmDuplicateStructure() {
|
|||
let sql: string;
|
||||
if (dbType === "mysql") {
|
||||
sql = `CREATE TABLE ${target} LIKE ${source};`;
|
||||
} else if (dbType === "postgres" || dbType === "redshift" || dbType === "gaussdb") {
|
||||
} else if (dbType && PG_LIKE_STRUCTURE_TYPES.has(dbType)) {
|
||||
sql = `CREATE TABLE ${target} (LIKE ${source} INCLUDING ALL);`;
|
||||
} else if (dbType === "sqlserver") {
|
||||
sql = `SELECT TOP 0 * INTO ${target} FROM ${source};`;
|
||||
} else if (dbType === "oracle" || dbType === "dameng") {
|
||||
} else if (usesFetchFirst(dbType)) {
|
||||
sql = `CREATE TABLE ${target} AS SELECT * FROM ${source} WHERE 1=0`;
|
||||
} else {
|
||||
sql = `CREATE TABLE ${target} AS SELECT * FROM ${source} WHERE 0;`;
|
||||
|
|
@ -536,7 +486,7 @@ async function collectDatabaseExportTables(): Promise<Array<{ schema?: string; n
|
|||
}));
|
||||
}
|
||||
|
||||
if (isSchemaAwareDbType(config?.db_type)) {
|
||||
if (isSchemaAware(config?.db_type)) {
|
||||
const schemas = await api.listSchemas(node.connectionId, node.database);
|
||||
const groups = await Promise.all(
|
||||
schemas.map(async (schema) => {
|
||||
|
|
@ -685,11 +635,7 @@ async function exportData(format: "csv" | "json" | "sql") {
|
|||
try {
|
||||
await connectionStore.ensureConnected(node.connectionId);
|
||||
const qualifiedName =
|
||||
(config.db_type === "postgres" ||
|
||||
config.db_type === "oracle" ||
|
||||
config.db_type === "sqlserver" ||
|
||||
config.db_type === "dameng") &&
|
||||
node.schema
|
||||
isSchemaAware(config.db_type) && node.schema
|
||||
? `${quoteIdent(node.schema)}.${quoteIdent(node.label)}`
|
||||
: quoteIdent(node.label);
|
||||
const result = await api.executeQuery(node.connectionId, node.database, `SELECT * FROM ${qualifiedName}`);
|
||||
|
|
@ -836,26 +782,29 @@ const canExpand = !leafTypes.has(props.node.type);
|
|||
const canPin = computed(() => pinnableTypes.has(props.node.type));
|
||||
const canOpenSqlFileExecution = computed(() => {
|
||||
const config = props.node.connectionId ? connectionStore.getConfig(props.node.connectionId) : undefined;
|
||||
return !!config && !sqlFileUnsupportedTypes.has(config.db_type);
|
||||
return !!config && !SQL_FILE_UNSUPPORTED_TYPES.has(config.db_type);
|
||||
});
|
||||
const canOpenDiagram = computed(() => {
|
||||
const config = props.node.connectionId ? connectionStore.getConfig(props.node.connectionId) : undefined;
|
||||
return !!props.node.database && !!config && diagramSupportedTypes.has(config.db_type);
|
||||
return !!props.node.database && !!config && DIAGRAM_SUPPORTED_TYPES.has(config.db_type);
|
||||
});
|
||||
const canOpenDatabaseSearch = computed(() => {
|
||||
const config = props.node.connectionId ? connectionStore.getConfig(props.node.connectionId) : undefined;
|
||||
return !!props.node.database && !!config && databaseSearchSupportedTypes.has(config.db_type);
|
||||
return !!props.node.database && !!config && DATABASE_SEARCH_SUPPORTED_TYPES.has(config.db_type);
|
||||
});
|
||||
const canOpenTableImport = computed(() => {
|
||||
const config = props.node.connectionId ? connectionStore.getConfig(props.node.connectionId) : undefined;
|
||||
return (
|
||||
props.node.type === "table" && !!props.node.database && !!config && tableImportSupportedTypes.has(config.db_type)
|
||||
props.node.type === "table" && !!props.node.database && !!config && TABLE_IMPORT_SUPPORTED_TYPES.has(config.db_type)
|
||||
);
|
||||
});
|
||||
const canOpenStructureEditor = computed(() => {
|
||||
const config = props.node.connectionId ? connectionStore.getConfig(props.node.connectionId) : undefined;
|
||||
return (
|
||||
props.node.type === "table" && !!props.node.database && !!config && tableStructureSupportedTypes.has(config.db_type)
|
||||
props.node.type === "table" &&
|
||||
!!props.node.database &&
|
||||
!!config &&
|
||||
TABLE_STRUCTURE_SUPPORTED_TYPES.has(config.db_type)
|
||||
);
|
||||
});
|
||||
const canOpenFieldLineage = computed(() => {
|
||||
|
|
@ -865,7 +814,7 @@ const canOpenFieldLineage = computed(() => {
|
|||
!!props.node.database &&
|
||||
!!props.node.tableName &&
|
||||
!!config &&
|
||||
fieldLineageSupportedTypes.has(config.db_type)
|
||||
FIELD_LINEAGE_SUPPORTED_TYPES.has(config.db_type)
|
||||
);
|
||||
});
|
||||
const isPinned = computed(() => props.node.pinned || connectionStore.isTreeNodePinned(props.node.id));
|
||||
|
|
|
|||
|
|
@ -12,6 +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 { nextTransferTerminalState } from "@/lib/transferProgressState";
|
||||
import { ArrowRightLeft, Check, X, Loader2, Square, CheckSquare } from "lucide-vue-next";
|
||||
|
||||
|
|
@ -25,19 +26,7 @@ const props = defineProps<{
|
|||
|
||||
const store = useConnectionStore();
|
||||
|
||||
const SQL_TYPES: DatabaseType[] = [
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"clickhouse",
|
||||
"duckdb",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
];
|
||||
|
||||
const sqlConnections = computed(() => store.connections.filter((c) => SQL_TYPES.includes(c.db_type)));
|
||||
const sqlConnections = computed(() => store.connections.filter((c) => TRANSFER_SQL_TYPES.has(c.db_type)));
|
||||
|
||||
// Source state
|
||||
const sourceConnectionId = ref("");
|
||||
|
|
@ -131,12 +120,7 @@ async function loadTables() {
|
|||
loadingTables.value = true;
|
||||
try {
|
||||
const config = store.getConfig(sourceConnectionId.value);
|
||||
const needsSchema =
|
||||
config?.db_type === "postgres" ||
|
||||
config?.db_type === "sqlserver" ||
|
||||
config?.db_type === "oracle" ||
|
||||
config?.db_type === "dameng" ||
|
||||
config?.db_type === "gaussdb";
|
||||
const needsSchema = isSchemaAware(config?.db_type);
|
||||
if (needsSchema) {
|
||||
const schemas = await api.listSchemas(sourceConnectionId.value, sourceDatabase.value);
|
||||
sourceSchema.value = schemas.includes("public") ? "public" : (schemas[0] ?? "");
|
||||
|
|
@ -223,12 +207,7 @@ async function startTransfer() {
|
|||
|
||||
// Auto-detect target schema
|
||||
const targetConfig = store.getConfig(targetConnectionId.value);
|
||||
const targetNeedsSchema =
|
||||
targetConfig?.db_type === "postgres" ||
|
||||
targetConfig?.db_type === "sqlserver" ||
|
||||
targetConfig?.db_type === "oracle" ||
|
||||
targetConfig?.db_type === "dameng" ||
|
||||
targetConfig?.db_type === "gaussdb";
|
||||
const targetNeedsSchema = isSchemaAware(targetConfig?.db_type);
|
||||
if (targetNeedsSchema && !targetSchema.value) {
|
||||
try {
|
||||
const schemas = await api.listSchemas(targetConnectionId.value, targetDatabase.value);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { ref } from "vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { isSchemaAware as isSchemaAwareType } from "@/lib/databaseCapabilities";
|
||||
import * as api from "@/lib/api";
|
||||
|
||||
export function useSchemaOptions() {
|
||||
|
|
@ -13,14 +14,7 @@ export function useSchemaOptions() {
|
|||
}
|
||||
|
||||
function isSchemaAware(connectionId: string): boolean {
|
||||
const dbType = connectionStore.getConfig(connectionId)?.db_type;
|
||||
return (
|
||||
dbType === "postgres" ||
|
||||
dbType === "sqlserver" ||
|
||||
dbType === "oracle" ||
|
||||
dbType === "dameng" ||
|
||||
dbType === "gaussdb"
|
||||
);
|
||||
return isSchemaAwareType(connectionStore.getConfig(connectionId)?.db_type);
|
||||
}
|
||||
|
||||
async function loadSchemaOptions(connectionId: string, database: string) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
import type { DatabaseType } from "@/types/database";
|
||||
|
||||
export const SCHEMA_AWARE_TYPES = new Set<DatabaseType>([
|
||||
"postgres",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
|
||||
export const SQL_FILE_UNSUPPORTED_TYPES = new Set<DatabaseType>(["redis", "mongodb", "elasticsearch"]);
|
||||
|
||||
export const DIAGRAM_SUPPORTED_TYPES = new Set<DatabaseType>([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
|
||||
export const DATABASE_SEARCH_SUPPORTED_TYPES = new Set<DatabaseType>([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"duckdb",
|
||||
"clickhouse",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
|
||||
export const TABLE_IMPORT_SUPPORTED_TYPES = new Set<DatabaseType>([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"duckdb",
|
||||
"clickhouse",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"doris",
|
||||
"starrocks",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
|
||||
export const TABLE_STRUCTURE_SUPPORTED_TYPES = new Set<DatabaseType>(["mysql", "postgres", "sqlite", "sqlserver"]);
|
||||
|
||||
export const FIELD_LINEAGE_SUPPORTED_TYPES = new Set<DatabaseType>([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
|
||||
export const FETCH_FIRST_TYPES = new Set<DatabaseType>(["oracle", "dameng"]);
|
||||
|
||||
export const TREE_SCHEMA_TYPES = new Set<DatabaseType>(["postgres", "sqlserver", "gaussdb"]);
|
||||
|
||||
export const PG_LIKE_STRUCTURE_TYPES = new Set<DatabaseType>(["postgres", "redshift", "gaussdb"]);
|
||||
|
||||
export const TRANSFER_SQL_TYPES = new Set<DatabaseType>([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"clickhouse",
|
||||
"duckdb",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
|
||||
export const DIAGRAM_SQL_TYPES = new Set<DatabaseType>([
|
||||
"mysql",
|
||||
"postgres",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"oracle",
|
||||
"redshift",
|
||||
"dameng",
|
||||
"gaussdb",
|
||||
]);
|
||||
|
||||
export function isSchemaAware(dbType?: DatabaseType): boolean {
|
||||
return !!dbType && SCHEMA_AWARE_TYPES.has(dbType);
|
||||
}
|
||||
|
||||
export function usesFetchFirst(dbType?: DatabaseType): boolean {
|
||||
return !!dbType && FETCH_FIRST_TYPES.has(dbType);
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import type { ColumnInfo, DatabaseType } from "../types/database.ts";
|
||||
import { qualifiedTableName, quoteTableIdentifier } from "./tableSelectSql.ts";
|
||||
import { usesFetchFirst } from "@/lib/databaseCapabilities";
|
||||
|
||||
export interface DatabaseSearchSqlOptions {
|
||||
databaseType?: DatabaseType;
|
||||
|
|
@ -133,7 +134,7 @@ export function buildDatabaseSearchSql(options: DatabaseSearchSqlOptions): Datab
|
|||
};
|
||||
}
|
||||
|
||||
if (options.databaseType === "oracle") {
|
||||
if (usesFetchFirst(options.databaseType)) {
|
||||
return {
|
||||
sql: `SELECT * FROM ${table} WHERE (${where}) FETCH FIRST ${limit} ROWS ONLY`,
|
||||
searchableColumns,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { DatabaseType } from "../types/database.ts";
|
||||
import { isSchemaAware, usesFetchFirst } from "@/lib/databaseCapabilities";
|
||||
|
||||
export interface BuildTableSelectSqlOptions {
|
||||
databaseType?: DatabaseType;
|
||||
|
|
@ -22,14 +23,7 @@ export function qualifiedTableName(
|
|||
options: Pick<BuildTableSelectSqlOptions, "databaseType" | "schema" | "tableName">,
|
||||
): string {
|
||||
const { databaseType, schema, tableName } = options;
|
||||
if (
|
||||
(databaseType === "postgres" ||
|
||||
databaseType === "oracle" ||
|
||||
databaseType === "sqlserver" ||
|
||||
databaseType === "dameng" ||
|
||||
databaseType === "gaussdb") &&
|
||||
schema
|
||||
) {
|
||||
if (isSchemaAware(databaseType) && schema) {
|
||||
return `${quoteTableIdentifier(databaseType, schema)}.${quoteTableIdentifier(databaseType, tableName)}`;
|
||||
}
|
||||
return quoteTableIdentifier(databaseType, tableName);
|
||||
|
|
@ -54,7 +48,7 @@ export function buildTableSelectSql(options: BuildTableSelectSqlOptions): string
|
|||
const orderBy = options.orderBy ?? defaultOrderBy;
|
||||
const order = orderBy ? ` ORDER BY ${orderBy}` : "";
|
||||
|
||||
if (databaseType === "oracle" || databaseType === "dameng") {
|
||||
if (usesFetchFirst(databaseType)) {
|
||||
const offset = options.offset ? ` OFFSET ${options.offset} ROWS` : "";
|
||||
return `SELECT * FROM ${table}${where}${order}${offset} FETCH FIRST ${limit} ROWS ONLY`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import {
|
|||
import type { SqlCompletionColumn, SqlCompletionTable } from "@/lib/sqlCompletion";
|
||||
import * as api from "@/lib/api";
|
||||
import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
import { isSchemaAware } from "@/lib/databaseCapabilities";
|
||||
|
||||
const PINNED_TREE_NODES_STORAGE_KEY = "dbx-pinned-tree-nodes";
|
||||
|
||||
|
|
@ -653,14 +654,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
|||
}
|
||||
|
||||
function isSchemaAwareDatabase(connectionId: string): boolean {
|
||||
const dbType = getConfig(connectionId)?.db_type;
|
||||
return (
|
||||
dbType === "postgres" ||
|
||||
dbType === "sqlserver" ||
|
||||
dbType === "oracle" ||
|
||||
dbType === "dameng" ||
|
||||
dbType === "gaussdb"
|
||||
);
|
||||
return isSchemaAware(getConfig(connectionId)?.db_type);
|
||||
}
|
||||
|
||||
async function listCompletionTables(connectionId: string, database: string): Promise<SqlCompletionTable[]> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue