mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-30 16:21:39 +00:00
feat: add Microsoft Access database support
Add Access as a new database type with agent-based connectivity, UCanAccess JDBC URL parsing, backtick identifier quoting, file-path connection dialog, and PNG icons for Access/GoldenDB/Vastbase.
This commit is contained in:
@@ -5,7 +5,7 @@ type ConnectionPresentationConfig = Pick<
|
||||
"db_type" | "driver_profile" | "driver_label" | "host" | "port" | "database"
|
||||
>;
|
||||
|
||||
const LOCAL_DATABASE_TYPES = new Set(["sqlite", "duckdb"]);
|
||||
const LOCAL_DATABASE_TYPES = new Set(["sqlite", "duckdb", "access"]);
|
||||
|
||||
export function connectionIconType(connection?: Pick<ConnectionConfig, "db_type" | "driver_profile">): string {
|
||||
return connection?.driver_profile || connection?.db_type || "postgres";
|
||||
@@ -45,6 +45,9 @@ export function connectionUrlPlaceholder(dbType: DatabaseType): string {
|
||||
case "duckdb":
|
||||
return "duckdb:///absolute/path/to/database.duckdb";
|
||||
|
||||
case "access":
|
||||
return "jdbc:ucanaccess:///absolute/path/to/database.accdb";
|
||||
|
||||
case "mongodb":
|
||||
return "mongodb://user:password@host:port/database";
|
||||
|
||||
|
||||
@@ -107,11 +107,36 @@ function parseJdbcSqlServerUrl(source: string): ParsedConnectionUrl | null {
|
||||
};
|
||||
}
|
||||
|
||||
function parseJdbcUCanAccessUrl(source: string): ParsedConnectionUrl | null {
|
||||
const match = source.match(/^jdbc:ucanaccess:\/\/(.+?)(?:;.*)?$/i);
|
||||
if (!match) return null;
|
||||
|
||||
const filePath = decodeUrlPart(match[1]);
|
||||
const normalizedPath = filePath.startsWith("/") || /^[A-Za-z]:[\\/]/.test(filePath) ? filePath : `/${filePath}`;
|
||||
const database = normalizedPath.split(/[\\/]/).filter(Boolean).pop();
|
||||
|
||||
return {
|
||||
dbType: "access",
|
||||
driverProfile: "access",
|
||||
driverLabel: "Microsoft Access",
|
||||
host: normalizedPath,
|
||||
port: 0,
|
||||
username: "",
|
||||
password: "",
|
||||
database,
|
||||
urlParams: "",
|
||||
ssl: false,
|
||||
connectionString: source,
|
||||
};
|
||||
}
|
||||
|
||||
export function parseConnectionUrl(value: string, preferredProfile?: string): ParsedConnectionUrl {
|
||||
const input = value.trim();
|
||||
if (!input) {
|
||||
throw new Error("Connection URL is empty");
|
||||
}
|
||||
const jdbcUCanAccess = parseJdbcUCanAccessUrl(input);
|
||||
if (jdbcUCanAccess) return jdbcUCanAccess;
|
||||
const jdbcSqlServer = parseJdbcSqlServerUrl(input);
|
||||
if (jdbcSqlServer) return jdbcSqlServer;
|
||||
const source = input.replace(/^jdbc:/i, "");
|
||||
|
||||
@@ -362,7 +362,8 @@ function buildPrimaryKeyWhere(
|
||||
columns: Array<string | undefined>,
|
||||
row: GridCellValue[],
|
||||
): string {
|
||||
if (databaseType === "hive" && primaryKeys.length === 0) return buildRowWhere(databaseType, columns, row);
|
||||
if ((databaseType === "hive" || databaseType === "access") && primaryKeys.length === 0)
|
||||
return buildRowWhere(databaseType, columns, row);
|
||||
return primaryKeys
|
||||
.map((primaryKey) => {
|
||||
const value = row[columns.indexOf(primaryKey)];
|
||||
|
||||
@@ -33,6 +33,7 @@ export const DIAGRAM_SUPPORTED_TYPES = new Set<DatabaseType>([
|
||||
"highgo",
|
||||
"vastbase",
|
||||
"goldendb",
|
||||
"access",
|
||||
"h2",
|
||||
"db2",
|
||||
]);
|
||||
@@ -52,6 +53,7 @@ export const DATABASE_SEARCH_SUPPORTED_TYPES = new Set<DatabaseType>([
|
||||
"highgo",
|
||||
"vastbase",
|
||||
"goldendb",
|
||||
"access",
|
||||
"h2",
|
||||
"snowflake",
|
||||
"trino",
|
||||
@@ -83,6 +85,7 @@ export const TABLE_IMPORT_SUPPORTED_TYPES = new Set<DatabaseType>([
|
||||
"highgo",
|
||||
"vastbase",
|
||||
"goldendb",
|
||||
"access",
|
||||
]);
|
||||
|
||||
export const TABLE_STRUCTURE_SUPPORTED_TYPES = new Set<DatabaseType>(["mysql", "postgres", "sqlite", "sqlserver"]);
|
||||
@@ -111,7 +114,7 @@ export const FIELD_LINEAGE_SUPPORTED_TYPES = new Set<DatabaseType>([
|
||||
"gaussdb",
|
||||
]);
|
||||
|
||||
export const SINGLE_DATABASE_TYPES = new Set<DatabaseType>(["oracle", "dameng"]);
|
||||
export const SINGLE_DATABASE_TYPES = new Set<DatabaseType>(["oracle", "dameng", "access"]);
|
||||
|
||||
export const FETCH_FIRST_TYPES = new Set<DatabaseType>(["oracle", "dameng"]);
|
||||
|
||||
@@ -137,6 +140,7 @@ export const AGENT_DRIVER_TYPES = new Set<DatabaseType>([
|
||||
"highgo",
|
||||
"vastbase",
|
||||
"goldendb",
|
||||
"access",
|
||||
"oracle",
|
||||
"h2",
|
||||
"snowflake",
|
||||
|
||||
@@ -35,6 +35,15 @@ const DEFAULT_CAPABILITY: DatabaseCapability = {
|
||||
};
|
||||
|
||||
const DATABASE_CAPABILITY_OVERRIDES: Partial<Record<DatabaseType, Partial<DatabaseCapability>>> = {
|
||||
access: {
|
||||
tableData: {
|
||||
insert: true,
|
||||
updateRequiresPrimaryKey: false,
|
||||
deleteRequiresPrimaryKey: false,
|
||||
requiresTransactionalTableForExistingRows: false,
|
||||
transaction: true,
|
||||
},
|
||||
},
|
||||
hive: {
|
||||
tableData: {
|
||||
insert: true,
|
||||
|
||||
@@ -17,7 +17,7 @@ export interface BuildTableSelectSqlOptions {
|
||||
}
|
||||
|
||||
export function quoteTableIdentifier(databaseType: DatabaseType | undefined, name: string): string {
|
||||
if (databaseType === "mysql" || databaseType === "hive" || databaseType === "tdengine")
|
||||
if (databaseType === "mysql" || databaseType === "hive" || databaseType === "tdengine" || databaseType === "access")
|
||||
return `\`${name.replace(/`/g, "``")}\``;
|
||||
if (databaseType === "informix" && /^[A-Za-z_][A-Za-z0-9_$]*$/.test(name)) return name;
|
||||
if (databaseType === "neo4j") return quoteCypherIdentifier(name);
|
||||
|
||||
Reference in New Issue
Block a user