131 lines
3.5 KiB
TypeScript
131 lines
3.5 KiB
TypeScript
import { access, readFile } from "node:fs/promises";
|
|
import { bridgePortFilePath, dbPath, appDataDir } from "./paths.js";
|
|
import { inspectConnectionStore } from "./connections.js";
|
|
|
|
export const DIRECT_QUERY_TYPES = ["postgres", "redshift", "mysql", "doris", "starrocks", "manticoresearch", "sqlite", "rqlite", "kwdb", "questdb"] as const;
|
|
|
|
export type DirectQueryType = (typeof DIRECT_QUERY_TYPES)[number];
|
|
|
|
const DIRECT_QUERY_TYPE_SET = new Set<string>(DIRECT_QUERY_TYPES);
|
|
|
|
export function isDirectQueryType(dbType: string): dbType is DirectQueryType {
|
|
return DIRECT_QUERY_TYPE_SET.has(dbType);
|
|
}
|
|
|
|
export const BRIDGE_REQUIRED_TYPES = [
|
|
"redis",
|
|
"mongodb",
|
|
"duckdb",
|
|
"clickhouse",
|
|
"sqlserver",
|
|
"oracle",
|
|
"elasticsearch",
|
|
"qdrant",
|
|
"milvus",
|
|
"weaviate",
|
|
"chromadb",
|
|
"etcd",
|
|
"dameng",
|
|
"kingbase",
|
|
"highgo",
|
|
"vastbase",
|
|
"goldendb",
|
|
"databend",
|
|
"gaussdb",
|
|
"yashandb",
|
|
"databricks",
|
|
"saphana",
|
|
"teradata",
|
|
"vertica",
|
|
"firebird",
|
|
"exasol",
|
|
"opengauss",
|
|
"oceanbase-oracle",
|
|
"gbase",
|
|
"tdengine",
|
|
"iotdb",
|
|
"h2",
|
|
"snowflake",
|
|
"trino",
|
|
"prestosql",
|
|
"hive",
|
|
"db2",
|
|
"informix",
|
|
"iris",
|
|
"neo4j",
|
|
"cassandra",
|
|
"bigquery",
|
|
"kylin",
|
|
"sundb",
|
|
"oscar",
|
|
"xugu",
|
|
"jdbc",
|
|
"access",
|
|
"influxdb",
|
|
"zookeeper",
|
|
] as const;
|
|
|
|
export interface DbxDiagnostics {
|
|
appDataDir: string;
|
|
dbPath: string;
|
|
dbPathExists: boolean;
|
|
connectionsTableExists: boolean;
|
|
connectionSecretsTableExists?: boolean;
|
|
connectionRowCount: number;
|
|
loadConnectionsOk: boolean;
|
|
loadedConnectionCount: number;
|
|
loadConnectionsError?: string;
|
|
loadConnectionsHint?: string;
|
|
bridgePortFile: string;
|
|
bridgePortFileExists: boolean;
|
|
bridgeUrl?: string;
|
|
directQueryTypes: string[];
|
|
bridgeRequiredTypes: string[];
|
|
}
|
|
|
|
export async function getDbxDiagnostics(): Promise<DbxDiagnostics> {
|
|
const portFile = bridgePortFilePath();
|
|
const bridgePortFileExists = await exists(portFile);
|
|
let bridgeUrl: string | undefined;
|
|
if (bridgePortFileExists) {
|
|
const port = (await readFile(portFile, "utf-8")).trim();
|
|
if (port) bridgeUrl = `http://127.0.0.1:${port}`;
|
|
}
|
|
|
|
const path = dbPath();
|
|
const connectionStore = await inspectConnectionStore({ path });
|
|
return {
|
|
appDataDir: appDataDir(),
|
|
dbPath: path,
|
|
dbPathExists: connectionStore.dbPathExists,
|
|
connectionsTableExists: connectionStore.connectionsTableExists,
|
|
connectionSecretsTableExists: connectionStore.connectionSecretsTableExists,
|
|
connectionRowCount: connectionStore.connectionRowCount,
|
|
loadConnectionsOk: connectionStore.loadConnectionsOk,
|
|
loadedConnectionCount: connectionStore.loadedConnectionCount,
|
|
loadConnectionsError: connectionStore.loadConnectionsError,
|
|
loadConnectionsHint: connectionStore.loadConnectionsError ? connectionStoreHint(connectionStore.loadConnectionsError) : undefined,
|
|
bridgePortFile: portFile,
|
|
bridgePortFileExists,
|
|
bridgeUrl,
|
|
directQueryTypes: [...DIRECT_QUERY_TYPES],
|
|
bridgeRequiredTypes: [...BRIDGE_REQUIRED_TYPES],
|
|
};
|
|
}
|
|
|
|
function connectionStoreHint(message: string): string | undefined {
|
|
if (/NODE_MODULE_VERSION|compiled against a different Node\.js version/i.test(message)) {
|
|
return "Rebuild DBX CLI native dependencies with your active Node.js: pnpm rebuild better-sqlite3 keytar --pending, or reinstall the package with the same Node.js version you use to run dbx.";
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
async function exists(path: string): Promise<boolean> {
|
|
try {
|
|
await access(path);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|