@flowblade/sqlduck 0.17.2 → 0.17.4
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 +37 -38
- package/dist/index.d.mts +33 -3
- package/dist/index.mjs +102 -29
- package/dist/validation/valibot/index.mjs +4 -0
- package/dist/validation/zod/index.d.mts +3 -3
- package/dist/validation/zod/index.mjs +1 -1
- package/dist/{zod-D87TPB5c.mjs → zod-CVF6XJKu.mjs} +17 -15
- package/package.json +21 -21
package/README.md
CHANGED
|
@@ -128,76 +128,75 @@ const queryResult = await dbDuckDbMemoryConn.query<{
|
|
|
128
128
|
|
|
129
129
|
## Benchmarks
|
|
130
130
|
|
|
131
|
-
### Node 24
|
|
131
|
+
### Node 24.15
|
|
132
132
|
|
|
133
133
|
```
|
|
134
|
+
RUN v4.1.5 /home/sebastien/github/flowblade/packages/sqlduck
|
|
134
135
|
|
|
135
|
-
RUN v4.1.4 /home/sebastien/github/flowblade/packages/sqlduck
|
|
136
136
|
|
|
137
|
+
✓ bench/appender.bench.ts > appender benches 3477ms
|
|
138
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
139
|
+
· duckdb appender memory, count: 100000, chunk size 2048 2.9578 336.81 339.37 338.09 339.37 339.37 339.37 339.37 ±4.82% 2
|
|
140
|
+
· duckdb appender file, count: 100000, chunk size 2048 1.5359 651.07 651.07 651.07 651.07 651.07 651.07 651.07 ±0.00% 1
|
|
141
|
+
· duckdb appender, count: 100000, chunk size 1024 2.8450 328.25 374.74 351.50 374.74 374.74 374.74 374.74 ±84.06% 2
|
|
137
142
|
|
|
138
|
-
✓ bench/
|
|
139
|
-
name hz min max mean p75 p99 p995 p999 rme samples
|
|
140
|
-
· duckdb appender memory, count: 100000, chunk size 2048 3.5446 265.91 298.32 282.12 298.32 298.32 298.32 298.32 ±72.99% 2
|
|
141
|
-
· duckdb appender file, count: 100000, chunk size 2048 2.6130 355.30 410.10 382.70 410.10 410.10 410.10 410.10 ±91.00% 2
|
|
142
|
-
· duckdb appender, count: 100000, chunk size 1024 3.8027 226.52 299.42 262.97 299.42 299.42 299.42 299.42 ±176.17% 2
|
|
143
|
-
|
|
144
|
-
✓ bench/stream.bench.ts > Bench rowsToColumnsChunks 2998ms
|
|
143
|
+
✓ bench/stream.bench.ts > Bench rowsToColumnsChunks 3514ms
|
|
145
144
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
146
|
-
· rowToColumnsChunk with chunkSize 2048 (count: 100000)
|
|
147
|
-
· rowToColumnsChunk with transformer with chunkSize 2048 (count: 100000)
|
|
148
|
-
· mapFakeRowStream with chunkSize 2048 (count: 100000)
|
|
145
|
+
· rowToColumnsChunk with chunkSize 2048 (count: 100000) 10.6932 76.7549 197.03 93.5173 88.9991 197.03 197.03 197.03 ±28.09% 10
|
|
146
|
+
· rowToColumnsChunk with transformer with chunkSize 2048 (count: 100000) 10.2660 87.8295 141.15 97.4092 97.0299 141.15 141.15 141.15 ±11.56% 10
|
|
147
|
+
· mapFakeRowStream with chunkSize 2048 (count: 100000) 8.3811 113.83 136.27 119.32 118.84 136.27 136.27 136.27 ±4.30% 10
|
|
149
148
|
|
|
150
|
-
✓ bench/table-create.bench.ts > Bench getTableCreateFromZod
|
|
149
|
+
✓ bench/table-create.bench.ts > Bench getTableCreateFromZod 614ms
|
|
151
150
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
152
|
-
· getTableCreateFromZod
|
|
151
|
+
· getTableCreateFromZod 20,399.65 0.0328 1.2897 0.0490 0.0425 0.1957 0.2681 0.6023 ±1.77% 10201
|
|
153
152
|
|
|
154
153
|
BENCH Summary
|
|
155
154
|
|
|
156
|
-
duckdb appender, count: 100000, chunk size
|
|
157
|
-
1.
|
|
158
|
-
1.
|
|
155
|
+
duckdb appender memory, count: 100000, chunk size 2048 - bench/appender.bench.ts > appender benches
|
|
156
|
+
1.04x faster than duckdb appender, count: 100000, chunk size 1024
|
|
157
|
+
1.93x faster than duckdb appender file, count: 100000, chunk size 2048
|
|
159
158
|
|
|
160
|
-
rowToColumnsChunk with
|
|
161
|
-
1.
|
|
162
|
-
1.
|
|
159
|
+
rowToColumnsChunk with chunkSize 2048 (count: 100000) - bench/stream.bench.ts > Bench rowsToColumnsChunks
|
|
160
|
+
1.04x faster than rowToColumnsChunk with transformer with chunkSize 2048 (count: 100000)
|
|
161
|
+
1.28x faster than mapFakeRowStream with chunkSize 2048 (count: 100000)
|
|
163
162
|
|
|
164
163
|
getTableCreateFromZod - bench/table-create.bench.ts > Bench getTableCreateFromZod
|
|
164
|
+
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
-
### Bun 1.3.
|
|
167
|
+
### Bun 1.3.13
|
|
168
168
|
|
|
169
169
|
```
|
|
170
|
-
RUN v4.1.
|
|
170
|
+
RUN v4.1.5 /home/sebastien/github/flowblade/packages/sqlduck
|
|
171
171
|
|
|
172
172
|
|
|
173
|
-
✓ bench/appender.bench.ts > appender benches
|
|
173
|
+
✓ bench/appender.bench.ts > appender benches 3382ms
|
|
174
174
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
175
|
-
· duckdb appender memory, count: 100000, chunk size 2048 3.
|
|
176
|
-
· duckdb appender file, count: 100000, chunk size 2048
|
|
177
|
-
· duckdb appender, count: 100000, chunk size 1024
|
|
175
|
+
· duckdb appender memory, count: 100000, chunk size 2048 3.0570 310.57 343.67 327.12 343.67 343.67 343.67 343.67 ±64.30% 2
|
|
176
|
+
· duckdb appender file, count: 100000, chunk size 2048 2.6163 377.75 386.70 382.22 386.70 386.70 386.70 386.70 ±14.88% 2
|
|
177
|
+
· duckdb appender, count: 100000, chunk size 1024 3.0427 319.38 337.93 328.65 337.93 337.93 337.93 337.93 ±35.86% 2
|
|
178
178
|
|
|
179
|
-
✓ bench/stream.bench.ts > Bench rowsToColumnsChunks
|
|
179
|
+
✓ bench/stream.bench.ts > Bench rowsToColumnsChunks 3075ms
|
|
180
180
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
181
|
-
· rowToColumnsChunk with chunkSize 2048 (count: 100000)
|
|
182
|
-
· rowToColumnsChunk with transformer with chunkSize 2048 (count: 100000)
|
|
183
|
-
· mapFakeRowStream with chunkSize 2048 (count: 100000)
|
|
181
|
+
· rowToColumnsChunk with chunkSize 2048 (count: 100000) 12.5039 68.9091 89.8222 79.9751 84.4430 89.8222 89.8222 89.8222 ±5.45% 10
|
|
182
|
+
· rowToColumnsChunk with transformer with chunkSize 2048 (count: 100000) 10.9097 83.6090 124.66 91.6616 92.3154 124.66 124.66 124.66 ±9.42% 10
|
|
183
|
+
· mapFakeRowStream with chunkSize 2048 (count: 100000) 10.2729 90.7410 104.18 97.3436 100.41 104.18 104.18 104.18 ±2.93% 10
|
|
184
184
|
|
|
185
|
-
✓ bench/table-create.bench.ts > Bench getTableCreateFromZod
|
|
185
|
+
✓ bench/table-create.bench.ts > Bench getTableCreateFromZod 629ms
|
|
186
186
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
187
|
-
· getTableCreateFromZod
|
|
187
|
+
· getTableCreateFromZod 20,285.23 0.0260 6.9886 0.0493 0.0466 0.1700 0.2249 2.6988 ±6.12% 10143
|
|
188
188
|
|
|
189
189
|
BENCH Summary
|
|
190
190
|
|
|
191
191
|
rowToColumnsChunk with chunkSize 2048 (count: 100000) - bench/stream.bench.ts > Bench rowsToColumnsChunks
|
|
192
|
-
1.
|
|
193
|
-
1.
|
|
192
|
+
1.15x faster than rowToColumnsChunk with transformer with chunkSize 2048 (count: 100000)
|
|
193
|
+
1.22x faster than mapFakeRowStream with chunkSize 2048 (count: 100000)
|
|
194
194
|
|
|
195
195
|
getTableCreateFromZod - bench/table-create.bench.ts > Bench getTableCreateFromZod
|
|
196
196
|
|
|
197
|
-
duckdb appender, count: 100000, chunk size
|
|
198
|
-
1.
|
|
199
|
-
1.
|
|
200
|
-
|
|
197
|
+
duckdb appender memory, count: 100000, chunk size 2048 - bench/appender.bench.ts > appender benches
|
|
198
|
+
1.00x faster than duckdb appender, count: 100000, chunk size 1024
|
|
199
|
+
1.17x faster than duckdb appender file, count: 100000, chunk size 2048
|
|
201
200
|
```
|
|
202
201
|
|
|
203
202
|
### Local scripts
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { n as DuckConnectionParams } from "./types-dnhcognF.mjs";
|
|
2
|
-
import * as _$_duckdb_node_api0 from "@duckdb/node-api";
|
|
3
2
|
import { DuckDBConnection, DuckDBType } from "@duckdb/node-api";
|
|
4
3
|
import * as _$_logtape_logtape0 from "@logtape/logtape";
|
|
5
4
|
import { Logger } from "@logtape/logtape";
|
|
@@ -276,6 +275,7 @@ type DuckDatabaseAttachCommandOptions = {
|
|
|
276
275
|
//#region src/manager/database/duck-database-manager.d.ts
|
|
277
276
|
declare class DuckDatabaseManager {
|
|
278
277
|
#private;
|
|
278
|
+
readonly className = "DuckDatabaseManager";
|
|
279
279
|
constructor(conn: DuckDBConnection, params?: {
|
|
280
280
|
logger?: Logger;
|
|
281
281
|
});
|
|
@@ -297,7 +297,7 @@ declare class DuckDatabaseManager {
|
|
|
297
297
|
attach: (dbParams: DuckConnectionParams, options?: DuckDatabaseAttachCommandOptions) => Promise<Database>;
|
|
298
298
|
attachOrReplace: (dbParams: DuckConnectionParams) => Promise<Database>;
|
|
299
299
|
attachIfNotExists: (dbParams: DuckConnectionParams) => Promise<Database>;
|
|
300
|
-
showDatabases: () => Promise<Record<string,
|
|
300
|
+
showDatabases: () => Promise<Record<string, unknown>[]>;
|
|
301
301
|
detach: (dbAlias: string) => Promise<boolean>;
|
|
302
302
|
detachIfExists: (dbAlias: string) => Promise<boolean>;
|
|
303
303
|
/**
|
|
@@ -322,6 +322,36 @@ declare class DuckDatabaseManager {
|
|
|
322
322
|
}>;
|
|
323
323
|
}
|
|
324
324
|
//#endregion
|
|
325
|
+
//#region src/manager/extensions/duck-extensions-manager.d.ts
|
|
326
|
+
declare class DuckExtensionsManager {
|
|
327
|
+
#private;
|
|
328
|
+
readonly className = "DuckExtensionsManager";
|
|
329
|
+
constructor(conn: DuckDBConnection, params?: {
|
|
330
|
+
logger?: Logger;
|
|
331
|
+
});
|
|
332
|
+
install: (name: string, params?: {
|
|
333
|
+
force?: boolean;
|
|
334
|
+
}) => Promise<true>;
|
|
335
|
+
search: (filters?: {
|
|
336
|
+
installed?: boolean;
|
|
337
|
+
name?: string;
|
|
338
|
+
}) => Promise<{
|
|
339
|
+
extension_name: string;
|
|
340
|
+
installed: boolean;
|
|
341
|
+
description: string;
|
|
342
|
+
}[]>;
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/manager/settings/duck-settings-manager.d.ts
|
|
346
|
+
declare class DuckSettingsManager {
|
|
347
|
+
#private;
|
|
348
|
+
readonly className = "DuckSettingsManager";
|
|
349
|
+
constructor(conn: DuckDBConnection, params?: {
|
|
350
|
+
logger?: Logger;
|
|
351
|
+
});
|
|
352
|
+
getCurrentSettings: <T extends string>(settings: T[]) => Promise<Record<T, string>>;
|
|
353
|
+
}
|
|
354
|
+
//#endregion
|
|
325
355
|
//#region src/config/flowblade-logtape-sqlduck.config.d.ts
|
|
326
356
|
declare const flowbladeLogtapeSqlduckConfig: {
|
|
327
357
|
categories: string[];
|
|
@@ -330,4 +360,4 @@ declare const flowbladeLogtapeSqlduckConfig: {
|
|
|
330
360
|
//#region src/logger/sqlduck-default-logtape-logger.d.ts
|
|
331
361
|
declare const sqlduckDefaultLogtapeLogger: _$_logtape_logtape0.Logger;
|
|
332
362
|
//#endregion
|
|
333
|
-
export { Database, type DuckConnectionParams, DuckDatabaseManager, DuckMemory, type DuckMemoryTag, type DuckdbReservedKeywords, type OnChunkAppendedCb, type OnChunkAppendedStats, SqlDuck, type SqlDuckParams, Table, type ToTableParams, duckReservedKeywords, flowbladeLogtapeSqlduckConfig, getTableCreateFromZod, sqlduckDefaultLogtapeLogger, zodCodecs };
|
|
363
|
+
export { Database, type DuckConnectionParams, DuckDatabaseManager, DuckExtensionsManager, DuckMemory, type DuckMemoryTag, DuckSettingsManager, type DuckdbReservedKeywords, type OnChunkAppendedCb, type OnChunkAppendedStats, SqlDuck, type SqlDuckParams, Table, type ToTableParams, duckReservedKeywords, flowbladeLogtapeSqlduckConfig, getTableCreateFromZod, sqlduckDefaultLogtapeLogger, zodCodecs };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as duckReservedKeywords } from "./duck-reserved-keywords-B8XUjnaY.mjs";
|
|
2
|
-
import { c as duckValidatorsZod, r as assertValidAliasName, s as duckConnectionParamsZodSchema } from "./zod-
|
|
2
|
+
import { c as duckValidatorsZod, r as assertValidAliasName, s as duckConnectionParamsZodSchema } from "./zod-CVF6XJKu.mjs";
|
|
3
3
|
import { BIGINT, BOOLEAN, DOUBLE, DuckDBDataChunk, DuckDBInstanceCache, DuckDBTimestampMillisecondsValue, DuckDBTypeId, ENUM, FLOAT, HUGEINT, INTEGER, SMALLINT, TIMESTAMP, TIMESTAMP_MS, TINYINT, UBIGINT, UHUGEINT, UINTEGER, USMALLINT, UTINYINT, UUID, VARCHAR } from "@duckdb/node-api";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import fs from "node:fs";
|
|
@@ -331,6 +331,38 @@ var Database = class {
|
|
|
331
331
|
}
|
|
332
332
|
};
|
|
333
333
|
//#endregion
|
|
334
|
+
//#region src/manager/core/manager-query-executor.ts
|
|
335
|
+
var ManagerQueryExecutor = class {
|
|
336
|
+
#conn;
|
|
337
|
+
#logger;
|
|
338
|
+
#className;
|
|
339
|
+
constructor(conn, className, params) {
|
|
340
|
+
this.#conn = conn;
|
|
341
|
+
this.#logger = params.logger;
|
|
342
|
+
this.#className = className;
|
|
343
|
+
}
|
|
344
|
+
getRowObjectsJS = async (name, rawSql) => {
|
|
345
|
+
const fnName = `${this.#className}.${name}`;
|
|
346
|
+
const startTime = Date.now();
|
|
347
|
+
try {
|
|
348
|
+
const result = await this.#conn.runAndReadAll(rawSql);
|
|
349
|
+
const timeMs = Math.round(Date.now() - startTime);
|
|
350
|
+
const data = result.getRowObjectsJS();
|
|
351
|
+
this.#logger.debug(`${fnName} in ${timeMs}ms`, { timeMs });
|
|
352
|
+
return data;
|
|
353
|
+
} catch (e) {
|
|
354
|
+
const msg = `Failed to run "${fnName}" - ${e?.message ?? ""}`;
|
|
355
|
+
const timeMs = Math.round(Date.now() - startTime);
|
|
356
|
+
this.#logger.error(msg, {
|
|
357
|
+
name: fnName,
|
|
358
|
+
sql: rawSql,
|
|
359
|
+
timeMs
|
|
360
|
+
});
|
|
361
|
+
throw new Error(msg, { cause: e });
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
//#endregion
|
|
334
366
|
//#region src/manager/database/commands/duck-database-attach-command.ts
|
|
335
367
|
var DuckDatabaseAttachCommand = class {
|
|
336
368
|
options;
|
|
@@ -391,9 +423,12 @@ var DuckDatabaseManager = class {
|
|
|
391
423
|
#conn;
|
|
392
424
|
#logger;
|
|
393
425
|
#fs;
|
|
426
|
+
#executor;
|
|
427
|
+
className = "DuckDatabaseManager";
|
|
394
428
|
constructor(conn, params) {
|
|
395
429
|
this.#conn = conn;
|
|
396
|
-
this.#logger = params?.logger ?? sqlduckDefaultLogtapeLogger.with({ source:
|
|
430
|
+
this.#logger = params?.logger ?? sqlduckDefaultLogtapeLogger.with({ source: this.className });
|
|
431
|
+
this.#executor = new ManagerQueryExecutor(this.#conn, this.className, { logger: this.#logger });
|
|
397
432
|
}
|
|
398
433
|
/**
|
|
399
434
|
* Attach a database to the current connection
|
|
@@ -414,7 +449,7 @@ var DuckDatabaseManager = class {
|
|
|
414
449
|
const params = duckConnectionParamsZodSchema.parse(dbParams);
|
|
415
450
|
const rawSql = new DuckDatabaseAttachCommand(params, options).getRawSql();
|
|
416
451
|
const { behaviour } = options ?? {};
|
|
417
|
-
await this.#
|
|
452
|
+
await this.#executor.getRowObjectsJS([
|
|
418
453
|
`attach(${params.alias}`,
|
|
419
454
|
behaviour ?? null,
|
|
420
455
|
")"
|
|
@@ -428,16 +463,16 @@ var DuckDatabaseManager = class {
|
|
|
428
463
|
return this.attach(dbParams, { behaviour: "IF NOT EXISTS" });
|
|
429
464
|
};
|
|
430
465
|
showDatabases = async () => {
|
|
431
|
-
return await this.#
|
|
466
|
+
return await this.#executor.getRowObjectsJS("showDatabases()", `SHOW DATABASES`);
|
|
432
467
|
};
|
|
433
468
|
detach = async (dbAlias) => {
|
|
434
469
|
assertValidAliasName(dbAlias);
|
|
435
|
-
await this.#
|
|
470
|
+
await this.#executor.getRowObjectsJS(`detach(${dbAlias})`, `DETACH ${dbAlias}`);
|
|
436
471
|
return true;
|
|
437
472
|
};
|
|
438
473
|
detachIfExists = async (dbAlias) => {
|
|
439
474
|
assertValidAliasName(dbAlias);
|
|
440
|
-
await this.#
|
|
475
|
+
await this.#executor.getRowObjectsJS(`detachIfExists(${dbAlias})`, `DETACH IF EXISTS ${dbAlias}`);
|
|
441
476
|
return true;
|
|
442
477
|
};
|
|
443
478
|
/**
|
|
@@ -449,16 +484,16 @@ var DuckDatabaseManager = class {
|
|
|
449
484
|
* @link https://duckdb.org/docs/stable/sql/statements/analyze
|
|
450
485
|
*/
|
|
451
486
|
analyze = async () => {
|
|
452
|
-
await this.#
|
|
487
|
+
await this.#executor.getRowObjectsJS("analyze()", "ANALYZE");
|
|
453
488
|
return true;
|
|
454
489
|
};
|
|
455
490
|
checkpoint = async (dbAlias) => {
|
|
456
491
|
const safeAlias = duckValidatorsZod.aliasName.parse(dbAlias);
|
|
457
|
-
await this.#
|
|
492
|
+
await this.#executor.getRowObjectsJS(`checkpoint(${safeAlias})`, `CHECKPOINT ${safeAlias}`);
|
|
458
493
|
return true;
|
|
459
494
|
};
|
|
460
495
|
vacuum = async () => {
|
|
461
|
-
await this.#
|
|
496
|
+
await this.#executor.getRowObjectsJS("vacuum()", "VACUUM");
|
|
462
497
|
return true;
|
|
463
498
|
};
|
|
464
499
|
/**
|
|
@@ -487,25 +522,6 @@ var DuckDatabaseManager = class {
|
|
|
487
522
|
}
|
|
488
523
|
return { status: "created" };
|
|
489
524
|
};
|
|
490
|
-
#executeRawSqlCommand = async (name, rawSql) => {
|
|
491
|
-
const startTime = Date.now();
|
|
492
|
-
try {
|
|
493
|
-
const result = await this.#conn.runAndReadAll(rawSql);
|
|
494
|
-
const timeMs = Math.round(Date.now() - startTime);
|
|
495
|
-
const data = result.getRowObjectsJS();
|
|
496
|
-
this.#logger.debug(`DuckDatabaseManager.${name} in ${timeMs}ms`, { timeMs });
|
|
497
|
-
return data;
|
|
498
|
-
} catch (e) {
|
|
499
|
-
const msg = `DuckDatabaseManager: failed to run "${name}" - ${e?.message ?? ""}`;
|
|
500
|
-
const timeMs = Math.round(Date.now() - startTime);
|
|
501
|
-
this.#logger.error(msg, {
|
|
502
|
-
name,
|
|
503
|
-
sql: rawSql,
|
|
504
|
-
timeMs
|
|
505
|
-
});
|
|
506
|
-
throw new Error(msg, { cause: e });
|
|
507
|
-
}
|
|
508
|
-
};
|
|
509
525
|
#getFs = () => {
|
|
510
526
|
if (this.#fs === void 0) this.#fs = new FileSystemUtils({ logger: this.#logger });
|
|
511
527
|
return this.#fs;
|
|
@@ -929,4 +945,61 @@ var Table = class Table {
|
|
|
929
945
|
};
|
|
930
946
|
};
|
|
931
947
|
//#endregion
|
|
932
|
-
|
|
948
|
+
//#region src/manager/extensions/duck-extensions-manager.ts
|
|
949
|
+
var DuckExtensionsManager = class {
|
|
950
|
+
#conn;
|
|
951
|
+
#logger;
|
|
952
|
+
#executor;
|
|
953
|
+
className = "DuckExtensionsManager";
|
|
954
|
+
constructor(conn, params) {
|
|
955
|
+
this.#conn = conn;
|
|
956
|
+
this.#logger = params?.logger ?? sqlduckDefaultLogtapeLogger.with({ source: this.className });
|
|
957
|
+
this.#executor = new ManagerQueryExecutor(this.#conn, this.className, { logger: this.#logger });
|
|
958
|
+
}
|
|
959
|
+
install = async (name, params) => {
|
|
960
|
+
const { force } = params ?? {};
|
|
961
|
+
await this.#executor.getRowObjectsJS("install", `${force ? "FORCE " : ""} INSTALL ${name}`);
|
|
962
|
+
return true;
|
|
963
|
+
};
|
|
964
|
+
search = async (filters) => {
|
|
965
|
+
const { installed, name } = filters ?? {};
|
|
966
|
+
const conditions = [installed === void 0 ? "" : `installed = ${installed ? "true" : "false"}`, name === void 0 ? "" : `extension_name = '${name}'`].filter(Boolean);
|
|
967
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
968
|
+
return await this.#executor.getRowObjectsJS("showExtensions", `
|
|
969
|
+
SELECT extension_name, installed, description
|
|
970
|
+
FROM duckdb_extensions()
|
|
971
|
+
${where}
|
|
972
|
+
ORDER BY extension_name
|
|
973
|
+
`);
|
|
974
|
+
};
|
|
975
|
+
};
|
|
976
|
+
//#endregion
|
|
977
|
+
//#region src/manager/settings/duck-settings-manager.ts
|
|
978
|
+
var DuckSettingsManager = class {
|
|
979
|
+
#conn;
|
|
980
|
+
#logger;
|
|
981
|
+
#executor;
|
|
982
|
+
className = "DuckSettingsManager";
|
|
983
|
+
constructor(conn, params) {
|
|
984
|
+
this.#conn = conn;
|
|
985
|
+
this.#logger = params?.logger ?? sqlduckDefaultLogtapeLogger.with({ source: this.className });
|
|
986
|
+
this.#executor = new ManagerQueryExecutor(this.#conn, this.className, { logger: this.#logger });
|
|
987
|
+
}
|
|
988
|
+
getCurrentSettings = async (settings) => {
|
|
989
|
+
const fnName = `${this.className}.getCurrentSettings`;
|
|
990
|
+
const query = `SELECT ${settings.map((s) => {
|
|
991
|
+
return `current_setting('${s}') as '${s}'`;
|
|
992
|
+
}).join(",\n")}`;
|
|
993
|
+
const firstRow = (await this.#executor.getRowObjectsJS(fnName, query))[0];
|
|
994
|
+
if (firstRow === void 0) {
|
|
995
|
+
const msg = `Failed to get current settings - no rows returned`;
|
|
996
|
+
this.#logger.error(msg, { sql: query });
|
|
997
|
+
throw new Error(msg);
|
|
998
|
+
}
|
|
999
|
+
const currentSettings = {};
|
|
1000
|
+
for (const [key, value] of Object.entries(firstRow)) currentSettings[key] = typeof value === "string" ? value : String(value);
|
|
1001
|
+
return currentSettings;
|
|
1002
|
+
};
|
|
1003
|
+
};
|
|
1004
|
+
//#endregion
|
|
1005
|
+
export { Database, DuckDatabaseManager, DuckExtensionsManager, DuckMemory, DuckSettingsManager, SqlDuck, Table, duckReservedKeywords, flowbladeLogtapeSqlduckConfig, getTableCreateFromZod, sqlduckDefaultLogtapeLogger, zodCodecs };
|
|
@@ -19,6 +19,10 @@ const duckIdentifierValibotSchema = v.pipe(v.string(), v.minLength(1), v.maxLeng
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
const duckValidatorsValibot = {
|
|
22
|
+
/**
|
|
23
|
+
* Validate duckdb objects names like table, alias, and schemas
|
|
24
|
+
* for validity.
|
|
25
|
+
*/
|
|
22
26
|
aliasName: duckIdentifierValibotSchema,
|
|
23
27
|
schemaName: duckIdentifierValibotSchema,
|
|
24
28
|
tableName: duckIdentifierValibotSchema
|
|
@@ -7,7 +7,7 @@ declare function assertValidSchemaName(schemaName: string): asserts schemaName i
|
|
|
7
7
|
declare function assertValidTableName(tableName: string): asserts tableName is DuckTableName;
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/validation/zod/duck-dsn-zod-schema.d.ts
|
|
10
|
-
declare const duckDsnZodSchema: z.ZodPipe<z.ZodString, z.
|
|
10
|
+
declare const duckDsnZodSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
11
11
|
type: "memory";
|
|
12
12
|
alias: string;
|
|
13
13
|
options?: {
|
|
@@ -34,7 +34,7 @@ declare const duckDsnZodSchema: z.ZodPipe<z.ZodString, z.ZodPipe<z.ZodTransform<
|
|
|
34
34
|
encryptionKey?: string | undefined;
|
|
35
35
|
encryptionCipher?: "CBC" | "CTR" | "GCM" | undefined;
|
|
36
36
|
} | undefined;
|
|
37
|
-
}, string
|
|
37
|
+
}, string>>, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
38
38
|
type: z.ZodLiteral<"memory">;
|
|
39
39
|
alias: z.ZodString;
|
|
40
40
|
options: z.ZodOptional<z.ZodObject<{
|
|
@@ -85,7 +85,7 @@ declare const duckDsnZodSchema: z.ZodPipe<z.ZodString, z.ZodPipe<z.ZodTransform<
|
|
|
85
85
|
GCM: "GCM";
|
|
86
86
|
}>>;
|
|
87
87
|
}, z.core.$strict>>;
|
|
88
|
-
}, z.core.$strict>], "type"
|
|
88
|
+
}, z.core.$strict>], "type">>;
|
|
89
89
|
//#endregion
|
|
90
90
|
//#region src/validation/zod/duck-validators-zod.d.ts
|
|
91
91
|
/**
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as assertValidTableName, c as duckValidatorsZod, i as assertValidSchemaName, n as duckDsnZodSchema, o as duckAllConnectionOptionsZodSchema, r as assertValidAliasName, s as duckConnectionParamsZodSchema, t as ensureZodTableSchema } from "../../zod-
|
|
1
|
+
import { a as assertValidTableName, c as duckValidatorsZod, i as assertValidSchemaName, n as duckDsnZodSchema, o as duckAllConnectionOptionsZodSchema, r as assertValidAliasName, s as duckConnectionParamsZodSchema, t as ensureZodTableSchema } from "../../zod-CVF6XJKu.mjs";
|
|
2
2
|
export { assertValidAliasName, assertValidSchemaName, assertValidTableName, duckAllConnectionOptionsZodSchema, duckConnectionParamsZodSchema, duckDsnZodSchema, duckValidatorsZod, ensureZodTableSchema };
|
|
@@ -21,6 +21,10 @@ const duckIdentifierZodSchema = z.string().min(1).max(120).regex(duckIdentifierN
|
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
const duckValidatorsZod = {
|
|
24
|
+
/**
|
|
25
|
+
* Validate duckdb objects names like table, alias, and schemas
|
|
26
|
+
* for validity.
|
|
27
|
+
*/
|
|
24
28
|
aliasName: duckIdentifierZodSchema,
|
|
25
29
|
schemaName: duckIdentifierZodSchema,
|
|
26
30
|
tableName: duckIdentifierZodSchema
|
|
@@ -75,26 +79,24 @@ function assertValidTableName(tableName) {
|
|
|
75
79
|
}
|
|
76
80
|
//#endregion
|
|
77
81
|
//#region src/validation/zod/duck-dsn-zod-schema.ts
|
|
78
|
-
const duckDsnZodSchema = z.string().
|
|
82
|
+
const duckDsnZodSchema = z.string().transform((dsn, ctx) => {
|
|
79
83
|
const result = parseDsn(dsn);
|
|
80
|
-
if (result.success) {
|
|
81
|
-
|
|
82
|
-
const { path, ...options } = parsed.params ?? {};
|
|
83
|
-
return {
|
|
84
|
-
type: parsed.host,
|
|
85
|
-
alias: parsed.db,
|
|
86
|
-
...path ? { path } : {},
|
|
87
|
-
options: { ...options }
|
|
88
|
-
};
|
|
89
|
-
} else {
|
|
90
|
-
ctx.issues.push({
|
|
84
|
+
if (!result.success) {
|
|
85
|
+
ctx.addIssue({
|
|
91
86
|
code: "custom",
|
|
92
|
-
message: result.message
|
|
93
|
-
input: dsn
|
|
87
|
+
message: result.message
|
|
94
88
|
});
|
|
95
89
|
return z.NEVER;
|
|
96
90
|
}
|
|
97
|
-
|
|
91
|
+
const parsed = result.value;
|
|
92
|
+
const { path, ...options } = parsed.params ?? {};
|
|
93
|
+
return {
|
|
94
|
+
type: parsed.host,
|
|
95
|
+
alias: parsed.db,
|
|
96
|
+
...path === void 0 ? {} : { path },
|
|
97
|
+
options: { ...options }
|
|
98
|
+
};
|
|
99
|
+
}).pipe(duckConnectionParamsZodSchema);
|
|
98
100
|
//#endregion
|
|
99
101
|
//#region src/validation/zod/ensure-zod-table-schema.ts
|
|
100
102
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowblade/sqlduck",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"exports": {
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@flowblade/core": "^0.2.28",
|
|
60
|
-
"@flowblade/source-duckdb": "^0.20.
|
|
60
|
+
"@flowblade/source-duckdb": "^0.20.6",
|
|
61
61
|
"@flowblade/sql-tag": "^0.3.3",
|
|
62
|
-
"@httpx/assert": "^0.
|
|
63
|
-
"@httpx/dsn-parser": "^1.9.
|
|
62
|
+
"@httpx/assert": "^0.17.0",
|
|
63
|
+
"@httpx/dsn-parser": "^1.9.10",
|
|
64
64
|
"@httpx/plain-object": "^2.1.9",
|
|
65
|
-
"@logtape/logtape": "^2.0.
|
|
65
|
+
"@logtape/logtape": "^2.0.7",
|
|
66
66
|
"@standard-schema/spec": "^1.1.0",
|
|
67
67
|
"is-safe-filename": "0.1.1",
|
|
68
|
-
"p-queue": "9.
|
|
69
|
-
"zod": "^4.3
|
|
68
|
+
"p-queue": "^9.2.0",
|
|
69
|
+
"zod": "^4.4.3"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
72
|
"@duckdb/node-api": "^1.5.2-r.1",
|
|
@@ -78,34 +78,34 @@
|
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@belgattitude/eslint-config-bases": "8.
|
|
82
|
-
"@dotenvx/dotenvx": "1.
|
|
81
|
+
"@belgattitude/eslint-config-bases": "8.15.0",
|
|
82
|
+
"@dotenvx/dotenvx": "1.64.0",
|
|
83
83
|
"@duckdb/node-api": "1.5.2-r.1",
|
|
84
84
|
"@faker-js/faker": "10.4.0",
|
|
85
|
-
"@flowblade/source-kysely": "^1.3.
|
|
86
|
-
"@httpx/assert": "0.
|
|
85
|
+
"@flowblade/source-kysely": "^1.3.4",
|
|
86
|
+
"@httpx/assert": "0.17.0",
|
|
87
87
|
"@mitata/counters": "0.0.8",
|
|
88
88
|
"@size-limit/esbuild": "12.1.0",
|
|
89
89
|
"@size-limit/file": "12.1.0",
|
|
90
90
|
"@testcontainers/mssqlserver": "11.14.0",
|
|
91
91
|
"@total-typescript/ts-reset": "0.6.1",
|
|
92
92
|
"@types/node": "25.6.0",
|
|
93
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
94
|
-
"@typescript-eslint/parser": "8.
|
|
95
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
96
|
-
"@vitest/coverage-v8": "4.1.
|
|
97
|
-
"@vitest/ui": "4.1.
|
|
93
|
+
"@typescript-eslint/eslint-plugin": "8.59.2",
|
|
94
|
+
"@typescript-eslint/parser": "8.59.2",
|
|
95
|
+
"@typescript/native-preview": "7.0.0-dev.20260503.1",
|
|
96
|
+
"@vitest/coverage-v8": "4.1.5",
|
|
97
|
+
"@vitest/ui": "4.1.5",
|
|
98
98
|
"ansis": "4.2.0",
|
|
99
99
|
"browserslist-to-esbuild": "2.1.1",
|
|
100
100
|
"core-js": "3.49.0",
|
|
101
101
|
"cross-env": "10.1.0",
|
|
102
102
|
"es-check": "9.6.4",
|
|
103
|
-
"es-toolkit": "1.
|
|
103
|
+
"es-toolkit": "1.46.1",
|
|
104
104
|
"esbuild": "0.28.0",
|
|
105
105
|
"eslint": "8.57.1",
|
|
106
106
|
"execa": "9.6.1",
|
|
107
107
|
"is-in-ci": "2.0.0",
|
|
108
|
-
"kysely": "0.28.
|
|
108
|
+
"kysely": "0.28.17",
|
|
109
109
|
"mitata": "1.0.34",
|
|
110
110
|
"npm-run-all2": "8.0.4",
|
|
111
111
|
"prettier": "3.8.3",
|
|
@@ -117,13 +117,13 @@
|
|
|
117
117
|
"tarn": "3.0.2",
|
|
118
118
|
"tedious": "19.2.1",
|
|
119
119
|
"testcontainers": "11.14.0",
|
|
120
|
-
"tsdown": "0.21.
|
|
120
|
+
"tsdown": "0.21.10",
|
|
121
121
|
"tsx": "4.21.0",
|
|
122
122
|
"typedoc": "0.28.19",
|
|
123
123
|
"typedoc-plugin-markdown": "4.11.0",
|
|
124
|
-
"typescript": "6.0.
|
|
124
|
+
"typescript": "6.0.3",
|
|
125
125
|
"valibot": "1.3.1",
|
|
126
|
-
"vitest": "4.1.
|
|
126
|
+
"vitest": "4.1.5"
|
|
127
127
|
},
|
|
128
128
|
"files": [
|
|
129
129
|
"dist"
|