@leonardovida-md/drizzle-neo-duckdb 1.0.3 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -5
- package/dist/client.d.ts +7 -1
- package/dist/columns.d.ts +6 -1
- package/dist/dialect.d.ts +21 -0
- package/dist/driver.d.ts +33 -1
- package/dist/duckdb-introspect.mjs +610 -114
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.mjs +319 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +603 -117
- package/dist/introspect.d.ts +9 -0
- package/dist/pool.d.ts +30 -0
- package/dist/session.d.ts +7 -1
- package/dist/sql/query-rewriters.d.ts +1 -1
- package/dist/sql/result-mapper.d.ts +7 -0
- package/dist/utils.d.ts +1 -1
- package/dist/value-wrappers-core.d.ts +42 -0
- package/dist/value-wrappers.d.ts +2 -98
- package/package.json +6 -2
- package/src/bin/duckdb-introspect.ts +27 -0
- package/src/client.ts +54 -13
- package/src/columns.ts +10 -10
- package/src/dialect.ts +51 -3
- package/src/driver.ts +204 -7
- package/src/helpers.ts +18 -0
- package/src/index.ts +1 -0
- package/src/introspect.ts +47 -29
- package/src/migrator.ts +1 -1
- package/src/olap.ts +1 -0
- package/src/pool.ts +274 -0
- package/src/session.ts +134 -15
- package/src/sql/query-rewriters.ts +177 -116
- package/src/sql/result-mapper.ts +7 -7
- package/src/utils.ts +1 -1
- package/src/value-wrappers-core.ts +156 -0
- package/src/value-wrappers.ts +60 -219
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://www.npmjs.com/package/@leonardovida-md/drizzle-neo-duckdb)
|
|
8
8
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
9
9
|
|
|
10
|
-
[Documentation](https://leonardovida-
|
|
10
|
+
[Documentation](https://leonardovida.github.io/drizzle-neo-duckdb/) • [LLM Context](https://leonardovida.github.io/drizzle-neo-duckdb/llms.txt) • [Examples](./example) • [Contributing](#contributing)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -19,6 +19,8 @@ Works with local DuckDB files, in-memory databases, and [MotherDuck](https://mot
|
|
|
19
19
|
|
|
20
20
|
> **Status:** Experimental. Core query building, migrations, and type inference work well. Some DuckDB-specific types and edge cases are still being refined.
|
|
21
21
|
|
|
22
|
+
Docs tip: every docs page has a **Markdown (raw)** button for LLM-friendly source.
|
|
23
|
+
|
|
22
24
|
## Installation
|
|
23
25
|
|
|
24
26
|
```bash
|
|
@@ -188,7 +190,20 @@ const products = pgTable('products', {
|
|
|
188
190
|
});
|
|
189
191
|
```
|
|
190
192
|
|
|
191
|
-
See [Column Types Documentation](https://leonardovida
|
|
193
|
+
See [Column Types Documentation](https://leonardovida.github.io/drizzle-neo-duckdb/api/columns) for complete reference.
|
|
194
|
+
|
|
195
|
+
### Client-Safe Imports (schemas, drizzle-zod, trpc)
|
|
196
|
+
|
|
197
|
+
When generated schemas are consumed in client bundles, import the helpers from the browser-safe subpath to avoid pulling the native DuckDB bindings:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import {
|
|
201
|
+
duckDbJson,
|
|
202
|
+
duckDbList,
|
|
203
|
+
} from '@leonardovida-md/drizzle-neo-duckdb/helpers';
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The introspection CLI now emits this import path by default. You can still override `importBasePath` if you need the old root import.
|
|
192
207
|
|
|
193
208
|
## Querying
|
|
194
209
|
|
|
@@ -275,7 +290,7 @@ import { migrate } from '@leonardovida-md/drizzle-neo-duckdb';
|
|
|
275
290
|
await migrate(db, { migrationsFolder: './drizzle' });
|
|
276
291
|
```
|
|
277
292
|
|
|
278
|
-
Migration metadata is stored in `drizzle.__drizzle_migrations` by default. See [Migrations Documentation](https://leonardovida
|
|
293
|
+
Migration metadata is stored in `drizzle.__drizzle_migrations` by default. See [Migrations Documentation](https://leonardovida.github.io/drizzle-neo-duckdb/guide/migrations) for configuration options.
|
|
279
294
|
|
|
280
295
|
## Schema Introspection
|
|
281
296
|
|
|
@@ -300,7 +315,7 @@ const result = await introspect(db, {
|
|
|
300
315
|
console.log(result.files.schemaTs);
|
|
301
316
|
```
|
|
302
317
|
|
|
303
|
-
See [Introspection Documentation](https://leonardovida
|
|
318
|
+
See [Introspection Documentation](https://leonardovida.github.io/drizzle-neo-duckdb/guide/introspection) for all options.
|
|
304
319
|
|
|
305
320
|
## Configuration Options
|
|
306
321
|
|
|
@@ -333,7 +348,7 @@ This connector aims for compatibility with Drizzle's Postgres driver but has som
|
|
|
333
348
|
| Prepared statements | No statement caching |
|
|
334
349
|
| Streaming results | Materialized by default; use `executeBatches()` for chunks |
|
|
335
350
|
|
|
336
|
-
See [Limitations Documentation](https://leonardovida
|
|
351
|
+
See [Limitations Documentation](https://leonardovida.github.io/drizzle-neo-duckdb/guide/limitations) for details.
|
|
337
352
|
|
|
338
353
|
## Examples
|
|
339
354
|
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { type DuckDBConnection } from '@duckdb/node-api';
|
|
2
|
-
export type DuckDBClientLike = DuckDBConnection;
|
|
2
|
+
export type DuckDBClientLike = DuckDBConnection | DuckDBConnectionPool;
|
|
3
3
|
export type RowData = Record<string, unknown>;
|
|
4
|
+
export interface DuckDBConnectionPool {
|
|
5
|
+
acquire(): Promise<DuckDBConnection>;
|
|
6
|
+
release(connection: DuckDBConnection): void | Promise<void>;
|
|
7
|
+
close?(): Promise<void> | void;
|
|
8
|
+
}
|
|
9
|
+
export declare function isPool(client: DuckDBClientLike): client is DuckDBConnectionPool;
|
|
4
10
|
export interface PrepareParamsOptions {
|
|
5
11
|
rejectStringArrayLiterals?: boolean;
|
|
6
12
|
warnOnStringArrayLiteral?: () => void;
|
package/dist/columns.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type SQL } from 'drizzle-orm';
|
|
2
2
|
import type { SQLWrapper } from 'drizzle-orm/sql/sql';
|
|
3
|
-
import { type ListValueWrapper, type ArrayValueWrapper, type MapValueWrapper, type BlobValueWrapper, type JsonValueWrapper } from './value-wrappers.ts';
|
|
3
|
+
import { type ListValueWrapper, type ArrayValueWrapper, type MapValueWrapper, type BlobValueWrapper, type JsonValueWrapper } from './value-wrappers-core.ts';
|
|
4
4
|
type IntColType = 'SMALLINT' | 'INTEGER' | 'BIGINT' | 'HUGEINT' | 'USMALLINT' | 'UINTEGER' | 'UBIGINT' | 'UHUGEINT' | 'INT' | 'INT16' | 'INT32' | 'INT64' | 'INT128' | 'LONG' | 'VARINT';
|
|
5
5
|
type FloatColType = 'FLOAT' | 'DOUBLE';
|
|
6
6
|
type StringColType = 'STRING' | 'VARCHAR' | 'TEXT';
|
|
@@ -12,6 +12,11 @@ type ListColType = `${AnyColType}[]`;
|
|
|
12
12
|
type ArrayColType = `${AnyColType}[${number}]`;
|
|
13
13
|
type StructColType = `STRUCT (${string})`;
|
|
14
14
|
type Primitive = AnyColType | ListColType | ArrayColType | StructColType;
|
|
15
|
+
export declare function coerceArrayString(value: string): unknown[] | undefined;
|
|
16
|
+
export declare function formatLiteral(value: unknown, typeHint?: string): string;
|
|
17
|
+
export declare function buildListLiteral(values: unknown[], elementType?: string): SQL;
|
|
18
|
+
export declare function buildStructLiteral(value: Record<string, unknown>, schema?: Record<string, Primitive>): SQL;
|
|
19
|
+
export declare function buildMapLiteral(value: Record<string, unknown>, valueType?: string): SQL;
|
|
15
20
|
export declare const duckDbList: <TData = unknown>(name: string, elementType: AnyColType) => import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
|
|
16
21
|
name: string;
|
|
17
22
|
dataType: "custom";
|
package/dist/dialect.d.ts
CHANGED
|
@@ -5,7 +5,28 @@ import { type DriverValueEncoder, type QueryTypingsValue } from 'drizzle-orm';
|
|
|
5
5
|
export declare class DuckDBDialect extends PgDialect {
|
|
6
6
|
static readonly [entityKind]: string;
|
|
7
7
|
private hasPgJsonColumn;
|
|
8
|
+
private savepointsSupported;
|
|
9
|
+
/**
|
|
10
|
+
* Reset the PG JSON detection flag. Should be called before preparing a new query.
|
|
11
|
+
*/
|
|
12
|
+
resetPgJsonFlag(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Mark that a PG JSON/JSONB column was detected during query preparation.
|
|
15
|
+
*/
|
|
16
|
+
markPgJsonDetected(): void;
|
|
8
17
|
assertNoPgJsonColumns(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Check if savepoints are known to be unsupported for this dialect instance.
|
|
20
|
+
*/
|
|
21
|
+
areSavepointsUnsupported(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Mark that savepoints are supported for this dialect instance.
|
|
24
|
+
*/
|
|
25
|
+
markSavepointsSupported(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Mark that savepoints are not supported for this dialect instance.
|
|
28
|
+
*/
|
|
29
|
+
markSavepointsUnsupported(): void;
|
|
9
30
|
migrate(migrations: MigrationMeta[], session: PgSession, config: MigrationConfig | string): Promise<void>;
|
|
10
31
|
prepareTyping(encoder: DriverValueEncoder<unknown, unknown>): QueryTypingsValue;
|
|
11
32
|
}
|
package/dist/driver.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DuckDBInstance } from '@duckdb/node-api';
|
|
1
2
|
import { entityKind } from 'drizzle-orm/entity';
|
|
2
3
|
import type { Logger } from 'drizzle-orm/logger';
|
|
3
4
|
import { PgDatabase } from 'drizzle-orm/pg-core/db';
|
|
@@ -10,6 +11,7 @@ import { DuckDBSession } from './session.ts';
|
|
|
10
11
|
import { DuckDBDialect } from './dialect.ts';
|
|
11
12
|
import { DuckDBSelectBuilder } from './select-builder.ts';
|
|
12
13
|
import type { ExecuteInBatchesOptions, RowData } from './client.ts';
|
|
14
|
+
import { type DuckDBPoolConfig, type PoolPreset } from './pool.ts';
|
|
13
15
|
export interface PgDriverOptions {
|
|
14
16
|
logger?: Logger;
|
|
15
17
|
rewriteArrays?: boolean;
|
|
@@ -23,16 +25,46 @@ export declare class DuckDBDriver {
|
|
|
23
25
|
constructor(client: DuckDBClientLike, dialect: DuckDBDialect, options?: PgDriverOptions);
|
|
24
26
|
createSession(schema: RelationalSchemaConfig<TablesRelationalConfig> | undefined): DuckDBSession<Record<string, unknown>, TablesRelationalConfig>;
|
|
25
27
|
}
|
|
28
|
+
/** Connection configuration when using path-based connection */
|
|
29
|
+
export interface DuckDBConnectionConfig {
|
|
30
|
+
/** Database path: ':memory:', './file.duckdb', 'md:', 'md:database' */
|
|
31
|
+
path: string;
|
|
32
|
+
/** DuckDB instance options (e.g., motherduck_token) */
|
|
33
|
+
options?: Record<string, string>;
|
|
34
|
+
}
|
|
26
35
|
export interface DuckDBDrizzleConfig<TSchema extends Record<string, unknown> = Record<string, never>> extends DrizzleConfig<TSchema> {
|
|
27
36
|
rewriteArrays?: boolean;
|
|
28
37
|
rejectStringArrayLiterals?: boolean;
|
|
38
|
+
/** Pool configuration. Use preset name, size config, or false to disable. */
|
|
39
|
+
pool?: DuckDBPoolConfig | PoolPreset | false;
|
|
40
|
+
}
|
|
41
|
+
export interface DuckDBDrizzleConfigWithConnection<TSchema extends Record<string, unknown> = Record<string, never>> extends DuckDBDrizzleConfig<TSchema> {
|
|
42
|
+
/** Connection string or config object */
|
|
43
|
+
connection: string | DuckDBConnectionConfig;
|
|
44
|
+
}
|
|
45
|
+
export interface DuckDBDrizzleConfigWithClient<TSchema extends Record<string, unknown> = Record<string, never>> extends DuckDBDrizzleConfig<TSchema> {
|
|
46
|
+
/** Explicit client (connection or pool) */
|
|
47
|
+
client: DuckDBClientLike;
|
|
29
48
|
}
|
|
49
|
+
export declare function drizzle<TSchema extends Record<string, unknown> = Record<string, never>>(connectionString: string): Promise<DuckDBDatabase<TSchema, ExtractTablesWithRelations<TSchema>>>;
|
|
50
|
+
export declare function drizzle<TSchema extends Record<string, unknown> = Record<string, never>>(connectionString: string, config: DuckDBDrizzleConfig<TSchema>): Promise<DuckDBDatabase<TSchema, ExtractTablesWithRelations<TSchema>>>;
|
|
51
|
+
export declare function drizzle<TSchema extends Record<string, unknown> = Record<string, never>>(config: DuckDBDrizzleConfigWithConnection<TSchema>): Promise<DuckDBDatabase<TSchema, ExtractTablesWithRelations<TSchema>>>;
|
|
52
|
+
export declare function drizzle<TSchema extends Record<string, unknown> = Record<string, never>>(config: DuckDBDrizzleConfigWithClient<TSchema>): DuckDBDatabase<TSchema, ExtractTablesWithRelations<TSchema>>;
|
|
30
53
|
export declare function drizzle<TSchema extends Record<string, unknown> = Record<string, never>>(client: DuckDBClientLike, config?: DuckDBDrizzleConfig<TSchema>): DuckDBDatabase<TSchema, ExtractTablesWithRelations<TSchema>>;
|
|
31
54
|
export declare class DuckDBDatabase<TFullSchema extends Record<string, unknown> = Record<string, never>, TSchema extends TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>> extends PgDatabase<DuckDBQueryResultHKT, TFullSchema, TSchema> {
|
|
32
55
|
readonly dialect: DuckDBDialect;
|
|
33
56
|
readonly session: DuckDBSession<TFullSchema, TSchema>;
|
|
34
57
|
static readonly [entityKind]: string;
|
|
35
|
-
|
|
58
|
+
/** The underlying connection or pool */
|
|
59
|
+
readonly $client: DuckDBClientLike;
|
|
60
|
+
/** The DuckDB instance (when created from connection string) */
|
|
61
|
+
readonly $instance?: DuckDBInstance;
|
|
62
|
+
constructor(dialect: DuckDBDialect, session: DuckDBSession<TFullSchema, TSchema>, schema: RelationalSchemaConfig<TSchema> | undefined, client: DuckDBClientLike, instance?: DuckDBInstance);
|
|
63
|
+
/**
|
|
64
|
+
* Close the database connection pool and instance.
|
|
65
|
+
* Should be called when shutting down the application.
|
|
66
|
+
*/
|
|
67
|
+
close(): Promise<void>;
|
|
36
68
|
select(): DuckDBSelectBuilder<undefined>;
|
|
37
69
|
select<TSelection extends SelectedFields>(fields: TSelection): DuckDBSelectBuilder<TSelection>;
|
|
38
70
|
executeBatches<T extends RowData = RowData>(query: SQL, options?: ExecuteInBatchesOptions): AsyncGenerator<T[], void, void>;
|