Skip to content

Commit 77cc883

Browse files
authored
feat(duckdb-driver): Add support for local fs duckdb database path (#7799)
* Add support for duckdb database file path * Parameter must be undefined if no fields. * Fix linter errors
1 parent f8bf572 commit 77cc883

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

docs/pages/product/configuration/data-sources/duckdb.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ deployment][ref-demo-deployment] in Cube Cloud.
6262
| `CUBEJS_DB_DUCKDB_MEMORY_LIMIT` | The maximum memory limit for DuckDB. Equivalent to `SET memory_limit=<MEMORY_LIMIT>`. Default is 75% of available RAM | A valid memory limit |||
6363
| `CUBEJS_DB_DUCKDB_SCHEMA` | The [default search schema][link-duckdb-configuration-ref] | A valid schema name |||
6464
| `CUBEJS_DB_DUCKDB_MOTHERDUCK_TOKEN` | The service token to use for connections to MotherDuck | A valid [MotherDuck service token][motherduck-docs-svc-token] |||
65+
| `CUBEJS_DB_DUCKDB_DATABASE_PATH` | The database filepath to use for connection to a local database. | A valid duckdb database file path |||
6566
| `CUBEJS_DB_DUCKDB_S3_ACCESS_KEY_ID` | The Access Key ID to use for database connections | A valid Access Key ID |||
6667
| `CUBEJS_DB_DUCKDB_S3_SECRET_ACCESS_KEY` | The Secret Access Key to use for database connections | A valid Secret Access Key |||
6768
| `CUBEJS_DB_DUCKDB_S3_ENDPOINT` | The S3 endpoint | A valid [S3 endpoint][duckdb-docs-s3-import] |||

docs/pages/reference/configuration/environment-variables.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,14 @@ MotherDuck.
238238
| -------------------------------- | ---------------------- | --------------------- |
239239
| A valid MotherDuck service token | N/A | N/A |
240240

241+
## `CUBEJS_DB_DUCKDB_DATABASE_PATH`
242+
243+
The database filepath to use for connection to a local database.
244+
245+
| Possible Values | Default in Development | Default in Production |
246+
| --------------------------------- | ---------------------- | --------------------- |
247+
| A valid duckdb database file path | N/A | N/A |
248+
241249
## `CUBEJS_DB_DUCKDB_S3_ACCESS_KEY_ID`
242250

243251
The AWS Access Key ID to use for S3 connections.

packages/cubejs-backend-shared/src/env.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,16 @@ const variables: Record<string, (...args: any) => any> = {
14081408
]
14091409
),
14101410

1411+
duckdbDatabasePath: ({
1412+
dataSource
1413+
}: {
1414+
dataSource: string,
1415+
}) => (
1416+
process.env[
1417+
keyByDataSource('CUBEJS_DB_DUCKDB_DATABASE_PATH', dataSource)
1418+
]
1419+
),
1420+
14111421
duckdbS3Region: ({
14121422
dataSource
14131423
}: {

packages/cubejs-duckdb-driver/src/DuckDBDriver.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,26 @@ export class DuckDBDriver extends BaseDriver implements DriverInterface {
5757

5858
protected async init(): Promise<InitPromise> {
5959
const token = getEnv('duckdbMotherDuckToken', this.config);
60+
const dbPath = getEnv('duckdbDatabasePath', this.config);
61+
62+
// Determine the database URL based on the provided db_path or token
63+
let dbUrl: string;
64+
if (dbPath) {
65+
dbUrl = dbPath;
66+
} else if (token) {
67+
dbUrl = `md:?motherduck_token=${token}&custom_user_agent=Cube/${version}`;
68+
} else {
69+
dbUrl = ':memory:';
70+
}
71+
72+
let dbOptions;
73+
if (token) {
74+
dbOptions = { custom_user_agent: `Cube/${version}` };
75+
}
76+
77+
// Create a new Database instance with the determined URL and custom user agent
78+
const db = new Database(dbUrl, dbOptions);
6079

61-
const db = new Database(
62-
token ? `md:?motherduck_token=${token}&custom_user_agent=Cube/${version}` : ':memory:',
63-
{
64-
custom_user_agent: `Cube/${version}`,
65-
}
66-
);
6780
// Under the hood all methods of Database uses internal default connection, but there is no way to expose it
6881
const defaultConnection = db.connect();
6982
const execAsync: (sql: string, ...params: any[]) => Promise<void> = promisify(defaultConnection.exec).bind(defaultConnection) as any;

0 commit comments

Comments
 (0)