@flowblade/sqlduck 0.11.0 → 0.13.0

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 CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  > Currently experimental
4
4
 
5
+
6
+ - 🛡️ DuckDB table creation from Zod schemas.
7
+ - 🧩 Easily ingest data from generators or async iterables.
8
+
9
+
5
10
  ## Quick start
6
11
 
7
12
  ### Create a database connection
@@ -24,7 +29,7 @@ import { conn } from "./db.config.ts";
24
29
 
25
30
  const dbManager = new DuckDatabaseManager(conn);
26
31
  const database = await dbManager.attach({
27
- type: ':memory:', // can be 'duckdb', ...
32
+ type: 'memory', // can be 'duckdb', ...
28
33
  alias: 'mydb',
29
34
  options: { COMPRESS: 'false' },
30
35
  });
@@ -129,30 +134,31 @@ const queryResult = await dbDuckDbMemoryConn.query<{
129
134
  RUN v4.1.1 /home/sebastien/github/flowblade/packages/sqlduck
130
135
 
131
136
 
132
- ✓ bench/appender.bench.ts > appender benches 66030ms
133
- name hz min max mean p75 p99 p995 p999 rme samples
134
- · duckdb appender, count: 1000000, chunk size 2048 0.0642 15,577.01 15,577.01 15,577.01 15,577.01 15,577.01 15,577.01 15,577.01 ±0.00% 1
135
- · duckdb appender, count: 1000000, chunk size 1024 0.0579 17,263.44 17,263.44 17,263.44 17,263.44 17,263.44 17,263.44 17,263.44 ±0.00% 1
137
+ ✓ bench/appender.bench.ts > appender benches 4157ms
138
+ name hz min max mean p75 p99 p995 p999 rme samples
139
+ · duckdb appender memory, count: 100000, chunk size 2048 2.6950 357.08 385.05 371.06 385.05 385.05 385.05 385.05 ±47.90% 2
140
+ · duckdb appender file, count: 100000, chunk size 2048 1.4218 703.35 703.35 703.35 703.35 703.35 703.35 703.35 ±0.00% 1
141
+ · duckdb appender, count: 100000, chunk size 1024 2.5157 391.12 403.89 397.50 403.89 403.89 403.89 403.89 ±20.41% 2
136
142
 
137
- ✓ bench/stream.bench.ts > Bench stream 22923ms
138
- name hz min max mean p75 p99 p995 p999 rme samples
139
- · rowToColumnsChunk with chunkSize 2048 (count: 1000000) 1.2126 742.59 906.65 824.67 863.91 906.65 906.65 906.65 ±4.26% 10
140
- · mapFakeRowStream with chunkSize 2048 (count: 1000000) 0.8049 1,123.18 1,498.68 1,242.43 1,257.91 1,498.68 1,498.68 1,498.68 ±6.40% 10
143
+ ✓ bench/stream.bench.ts > Bench stream 2809ms
144
+ name hz min max mean p75 p99 p995 p999 rme samples
145
+ · rowToColumnsChunk with chunkSize 2048 (count: 100000) 9.2627 87.7271 151.56 107.96 116.92 151.56 151.56 151.56 ±15.98% 10
146
+ · mapFakeRowStream with chunkSize 2048 (count: 100000) 7.1479 125.04 168.13 139.90 152.97 168.13 168.13 168.13 ±7.78% 10
141
147
 
142
- ✓ bench/table-create.bench.ts > Bench getTableCreateFromZod 615ms
148
+ ✓ bench/table-create.bench.ts > Bench getTableCreateFromZod 614ms
143
149
  name hz min max mean p75 p99 p995 p999 rme samples
144
- · getTableCreateFromZod 16,562.93 0.0242 2.5902 0.0604 0.0734 0.2555 0.3741 0.8135 ±2.32% 8282
150
+ · getTableCreateFromZod 18,899.24 0.0334 5.3351 0.0529 0.0546 0.1943 0.3087 0.7214 ±2.72% 9450
145
151
 
146
152
  BENCH Summary
147
153
 
148
- duckdb appender, count: 1000000, chunk size 2048 - bench/appender.bench.ts > appender benches
149
- 1.11x faster than duckdb appender, count: 1000000, chunk size 1024
154
+ duckdb appender memory, count: 100000, chunk size 2048 - bench/appender.bench.ts > appender benches
155
+ 1.07x faster than duckdb appender, count: 100000, chunk size 1024
156
+ 1.90x faster than duckdb appender file, count: 100000, chunk size 2048
150
157
 
151
- rowToColumnsChunk with chunkSize 2048 (count: 1000000) - bench/stream.bench.ts > Bench stream
152
- 1.51x faster than mapFakeRowStream with chunkSize 2048 (count: 1000000)
158
+ rowToColumnsChunk with chunkSize 2048 (count: 100000) - bench/stream.bench.ts > Bench stream
159
+ 1.30x faster than mapFakeRowStream with chunkSize 2048 (count: 100000)
153
160
 
154
161
  getTableCreateFromZod - bench/table-create.bench.ts > Bench getTableCreateFromZod
155
-
156
162
  ```
157
163
 
158
164
  ### Bun 1.3.11
@@ -161,29 +167,31 @@ const queryResult = await dbDuckDbMemoryConn.query<{
161
167
  RUN v4.1.1 /home/sebastien/github/flowblade/packages/sqlduck
162
168
 
163
169
 
164
- ✓ bench/appender.bench.ts > appender benches 36627ms
165
- name hz min max mean p75 p99 p995 p999 rme samples
166
- · duckdb appender, count: 1000000, chunk size 2048 0.1177 8,495.41 8,495.41 8,495.41 8,495.41 8,495.41 8,495.41 8,495.41 ±0.00% 1
167
- · duckdb appender, count: 1000000, chunk size 1024 0.1064 9,397.97 9,397.97 9,397.97 9,397.97 9,397.97 9,397.97 9,397.97 ±0.00% 1
170
+ ✓ bench/appender.bench.ts > appender benches 4159ms
171
+ name hz min max mean p75 p99 p995 p999 rme samples
172
+ · duckdb appender memory, count: 100000, chunk size 2048 2.6465 375.34 380.38 377.86 380.38 380.38 380.38 380.38 ±8.48% 2
173
+ · duckdb appender file, count: 100000, chunk size 2048 1.5016 665.98 665.98 665.98 665.98 665.98 665.98 665.98 ±0.00% 1
174
+ · duckdb appender, count: 100000, chunk size 1024 2.2828 413.11 463.01 438.06 463.01 463.01 463.01 463.01 ±72.39% 2
168
175
 
169
- ✓ bench/stream.bench.ts > Bench stream 23421ms
170
- name hz min max mean p75 p99 p995 p999 rme samples
171
- · rowToColumnsChunk with chunkSize 2048 (count: 1000000) 1.1378 801.60 1,080.22 878.91 910.91 1,080.22 1,080.22 1,080.22 ±6.85% 10
172
- · mapFakeRowStream with chunkSize 2048 (count: 1000000) 0.8118 1,130.36 1,448.99 1,231.78 1,268.45 1,448.99 1,448.99 1,448.99 ±5.34% 10
176
+ ✓ bench/stream.bench.ts > Bench stream 2690ms
177
+ name hz min max mean p75 p99 p995 p999 rme samples
178
+ · rowToColumnsChunk with chunkSize 2048 (count: 100000) 9.5675 95.6610 114.11 104.52 107.75 114.11 114.11 114.11 ±3.46% 10
179
+ · mapFakeRowStream with chunkSize 2048 (count: 100000) 7.6895 117.83 138.26 130.05 137.51 138.26 138.26 138.26 ±4.05% 10
173
180
 
174
- ✓ bench/table-create.bench.ts > Bench getTableCreateFromZod 622ms
181
+ ✓ bench/table-create.bench.ts > Bench getTableCreateFromZod 629ms
175
182
  name hz min max mean p75 p99 p995 p999 rme samples
176
- · getTableCreateFromZod 22,447.94 0.0210 5.4621 0.0445 0.0442 0.1657 0.2167 2.5852 ±5.37% 11224
183
+ · getTableCreateFromZod 18,892.06 0.0281 7.5844 0.0529 0.0516 0.1893 0.2477 3.2823 ±6.26% 9447
177
184
 
178
185
  BENCH Summary
179
186
 
180
- rowToColumnsChunk with chunkSize 2048 (count: 1000000) - bench/stream.bench.ts > Bench stream
181
- 1.40x faster than mapFakeRowStream with chunkSize 2048 (count: 1000000)
187
+ rowToColumnsChunk with chunkSize 2048 (count: 100000) - bench/stream.bench.ts > Bench stream
188
+ 1.24x faster than mapFakeRowStream with chunkSize 2048 (count: 100000)
182
189
 
183
190
  getTableCreateFromZod - bench/table-create.bench.ts > Bench getTableCreateFromZod
184
191
 
185
- duckdb appender, count: 1000000, chunk size 2048 - bench/appender.bench.ts > appender benches
186
- 1.11x faster than duckdb appender, count: 1000000, chunk size 1024
192
+ duckdb appender memory, count: 100000, chunk size 2048 - bench/appender.bench.ts > appender benches
193
+ 1.16x faster than duckdb appender, count: 100000, chunk size 1024
194
+ 1.76x faster than duckdb appender file, count: 100000, chunk size 2048
187
195
 
188
196
  ```
189
197
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
- import * as _duckdb_node_api0 from "@duckdb/node-api";
1
+ import { n as DuckConnectionParams } from "./types-DCqYqEsa.mjs";
2
+ import * as _$_duckdb_node_api0 from "@duckdb/node-api";
2
3
  import { DuckDBConnection, DuckDBType } from "@duckdb/node-api";
3
- import * as _logtape_logtape0 from "@logtape/logtape";
4
+ import * as _$_logtape_logtape0 from "@logtape/logtape";
4
5
  import { Logger } from "@logtape/logtape";
5
6
  import * as z from "zod";
6
7
  import { ZodObject } from "zod";
@@ -137,6 +138,11 @@ type ToTableParams<TSchema extends TableSchemaZod> = {
137
138
  * Callback called each time a datachunk is appended to the table
138
139
  */
139
140
  onDataAppended?: OnDataAppendedCb;
141
+ /**
142
+ * Automatically checkpoint the table after all chunks have been appended.
143
+ * @default true
144
+ */
145
+ autoCheckpoint?: boolean;
140
146
  };
141
147
  type ToTableResult = {
142
148
  /**
@@ -218,64 +224,13 @@ declare class Database {
218
224
  [Symbol.toStringTag](): string;
219
225
  }
220
226
  //#endregion
221
- //#region src/manager/database/duck-database-manager.schemas.d.ts
222
- declare const duckDatabaseManagerDbParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
223
- type: z.ZodLiteral<":memory:">;
224
- alias: z.ZodString;
225
- options: z.ZodOptional<z.ZodObject<{
226
- ACCESS_MODE: z.ZodOptional<z.ZodEnum<{
227
- READ_ONLY: "READ_ONLY";
228
- READ_WRITE: "READ_WRITE";
229
- AUTOMATIC: "AUTOMATIC";
230
- }>>;
231
- COMPRESS: z.ZodOptional<z.ZodEnum<{
232
- true: "true";
233
- false: "false";
234
- }>>;
235
- TYPE: z.ZodOptional<z.ZodEnum<{
236
- DUCKDB: "DUCKDB";
237
- SQLITE: "SQLITE";
238
- }>>;
239
- BLOCK_SIZE: z.ZodOptional<z.ZodInt32>;
240
- ROW_GROUP_SIZE: z.ZodOptional<z.ZodInt32>;
241
- STORAGE_VERSION: z.ZodOptional<z.ZodString>;
242
- ENCRYPTION_KEY: z.ZodOptional<z.ZodString>;
243
- ENCRYPTION_CIPHER: z.ZodOptional<z.ZodEnum<{
244
- CBC: "CBC";
245
- CTR: "CTR";
246
- GCM: "GCM";
247
- }>>;
248
- }, z.core.$strict>>;
249
- }, z.core.$strict>, z.ZodObject<{
250
- type: z.ZodLiteral<"duckdb">;
251
- path: z.ZodString;
252
- alias: z.ZodString;
253
- options: z.ZodOptional<z.ZodObject<{
254
- ACCESS_MODE: z.ZodOptional<z.ZodEnum<{
255
- READ_ONLY: "READ_ONLY";
256
- READ_WRITE: "READ_WRITE";
257
- AUTOMATIC: "AUTOMATIC";
258
- }>>;
259
- COMPRESS: z.ZodOptional<z.ZodEnum<{
260
- true: "true";
261
- false: "false";
262
- }>>;
263
- TYPE: z.ZodOptional<z.ZodEnum<{
264
- DUCKDB: "DUCKDB";
265
- SQLITE: "SQLITE";
266
- }>>;
267
- BLOCK_SIZE: z.ZodOptional<z.ZodInt32>;
268
- ROW_GROUP_SIZE: z.ZodOptional<z.ZodInt32>;
269
- STORAGE_VERSION: z.ZodOptional<z.ZodString>;
270
- ENCRYPTION_KEY: z.ZodOptional<z.ZodString>;
271
- ENCRYPTION_CIPHER: z.ZodOptional<z.ZodEnum<{
272
- CBC: "CBC";
273
- CTR: "CTR";
274
- GCM: "GCM";
275
- }>>;
276
- }, z.core.$strict>>;
277
- }, z.core.$strict>], "type">;
278
- type DuckDatabaseManagerDbParams = z.infer<typeof duckDatabaseManagerDbParamsSchema>;
227
+ //#region src/validation/core/duck-reserved-keywords.d.ts
228
+ /**
229
+ * DuckDB reserved keywords that cannot be used as unquoted identifiers.
230
+ * @see https://duckdb.org/docs/sql/keywords-and-identifiers.html
231
+ */
232
+ declare const duckReservedKeywords: readonly ["ALL", "ANALYSE", "ANALYZE", "AND", "ANY", "ARRAY", "AS", "ASC", "ASYMMETRIC", "BOTH", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_CATALOG", "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "DEFAULT", "DEFERRABLE", "DESC", "DISTINCT", "DO", "ELSE", "END", "EXCEPT", "EXISTS", "EXTRACT", "FALSE", "FETCH", "FOR", "FOREIGN", "FROM", "GRANT", "GROUP", "HAVING", "IF", "ILIKE", "IN", "INITIALLY", "INNER", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "LATERAL", "LEADING", "LEFT", "LIKE", "LIMIT", "LOCALTIME", "LOCALTIMESTAMP", "NATURAL", "NOT", "NOTNULL", "NULL", "OFFSET", "ON", "ONLY", "OR", "ORDER", "OUTER", "OVERLAPS", "PLACING", "PRIMARY", "REFERENCES", "RETURNING", "RIGHT", "ROW", "SELECT", "SESSION_USER", "SIMILAR", "SOME", "SYMMETRIC", "TABLE", "THEN", "TO", "TRAILING", "TRUE", "UNION", "UNIQUE", "USING", "VARIADIC", "VERBOSE", "WHEN", "WHERE", "WINDOW", "WITH"];
233
+ type DuckdbReservedKeywords = (typeof duckReservedKeywords)[number];
279
234
  //#endregion
280
235
  //#region src/manager/database/commands/duck-database-attach-command.d.ts
281
236
  type Behaviour = 'OR REPLACE' | 'IF NOT EXISTS';
@@ -296,7 +251,7 @@ declare class DuckDatabaseManager {
296
251
  * ```typescript
297
252
  * const dbManager = new DuckDatabaseManager(conn);
298
253
  * const database = dbManager.attach({
299
- * type: ':memory:', // can be 'duckdb', 's3'...
254
+ * type: 'memory', // can be 'duckdb', 's3'...
300
255
  * alias: 'mydb',
301
256
  * options: { COMPRESS: 'true' }
302
257
  * });
@@ -304,10 +259,10 @@ declare class DuckDatabaseManager {
304
259
  * console.log(database.alias); // 'mydb'
305
260
  * ```
306
261
  */
307
- attach: (dbParams: DuckDatabaseManagerDbParams, options?: DuckDatabaseAttachCommandOptions) => Promise<Database>;
308
- attachOrReplace: (dbParams: DuckDatabaseManagerDbParams) => Promise<Database>;
309
- attachIfNotExists: (dbParams: DuckDatabaseManagerDbParams) => Promise<Database>;
310
- showDatabases: () => Promise<Record<string, _duckdb_node_api0.JS>[]>;
262
+ attach: (dbParams: DuckConnectionParams, options?: DuckDatabaseAttachCommandOptions) => Promise<Database>;
263
+ attachOrReplace: (dbParams: DuckConnectionParams) => Promise<Database>;
264
+ attachIfNotExists: (dbParams: DuckConnectionParams) => Promise<Database>;
265
+ showDatabases: () => Promise<Record<string, _$_duckdb_node_api0.JS>[]>;
311
266
  detach: (dbAlias: string) => Promise<boolean>;
312
267
  detachIfExists: (dbAlias: string) => Promise<boolean>;
313
268
  /**
@@ -320,26 +275,15 @@ declare class DuckDatabaseManager {
320
275
  */
321
276
  analyze: () => Promise<boolean>;
322
277
  checkpoint: (dbAlias: string) => Promise<boolean>;
278
+ vacuum: () => Promise<boolean>;
323
279
  }
324
280
  //#endregion
325
- //#region src/validation/core/duckdb-reserved-keywords.d.ts
326
- /**
327
- * DuckDB reserved keywords that cannot be used as unquoted identifiers.
328
- * @see https://duckdb.org/docs/sql/keywords-and-identifiers.html
329
- */
330
- declare const duckdbReservedKeywords: readonly ["ALL", "ANALYSE", "ANALYZE", "AND", "ANY", "ARRAY", "AS", "ASC", "ASYMMETRIC", "BOTH", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_CATALOG", "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "DEFAULT", "DEFERRABLE", "DESC", "DISTINCT", "DO", "ELSE", "END", "EXCEPT", "EXISTS", "EXTRACT", "FALSE", "FETCH", "FOR", "FOREIGN", "FROM", "GRANT", "GROUP", "HAVING", "IF", "ILIKE", "IN", "INITIALLY", "INNER", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "LATERAL", "LEADING", "LEFT", "LIKE", "LIMIT", "LOCALTIME", "LOCALTIMESTAMP", "NATURAL", "NOT", "NOTNULL", "NULL", "OFFSET", "ON", "ONLY", "OR", "ORDER", "OUTER", "OVERLAPS", "PLACING", "PRIMARY", "REFERENCES", "RETURNING", "RIGHT", "ROW", "SELECT", "SESSION_USER", "SIMILAR", "SOME", "SYMMETRIC", "TABLE", "THEN", "TO", "TRAILING", "TRUE", "UNION", "UNIQUE", "USING", "VARIADIC", "VERBOSE", "WHEN", "WHERE", "WINDOW", "WITH"];
331
- type DuckdbReservedKeywords = (typeof duckdbReservedKeywords)[number];
332
- //#endregion
333
- //#region src/validation/zod/duckdb-valid-names.schemas.d.ts
334
- declare const duckTableNameSchema: z.ZodString;
335
- declare const duckTableAliasSchema: z.ZodString;
336
- //#endregion
337
281
  //#region src/config/flowblade-logtape-sqlduck.config.d.ts
338
282
  declare const flowbladeLogtapeSqlduckConfig: {
339
283
  categories: string[];
340
284
  };
341
285
  //#endregion
342
286
  //#region src/logger/sqlduck-default-logtape-logger.d.ts
343
- declare const sqlduckDefaultLogtapeLogger: _logtape_logtape0.Logger;
287
+ declare const sqlduckDefaultLogtapeLogger: _$_logtape_logtape0.Logger;
344
288
  //#endregion
345
- export { Database, DuckDatabaseManager, type DuckDatabaseManagerDbParams, DuckMemory, type DuckMemoryTag, type DuckdbReservedKeywords, type OnDataAppendedCb, type OnDataAppendedStats, SqlDuck, type SqlDuckParams, Table, type ToTableParams, duckDatabaseManagerDbParamsSchema, duckTableAliasSchema, duckTableNameSchema, duckdbReservedKeywords, flowbladeLogtapeSqlduckConfig, getTableCreateFromZod, sqlduckDefaultLogtapeLogger, zodCodecs };
289
+ export { Database, type DuckConnectionParams, DuckDatabaseManager, DuckMemory, type DuckMemoryTag, type DuckdbReservedKeywords, type OnDataAppendedCb, type OnDataAppendedStats, SqlDuck, type SqlDuckParams, Table, type ToTableParams, duckReservedKeywords, flowbladeLogtapeSqlduckConfig, getTableCreateFromZod, sqlduckDefaultLogtapeLogger, zodCodecs };