@flowblade/sqlduck 0.34.0 → 0.36.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.
|
@@ -255,7 +255,7 @@ type MapRelaxedZodSchemaField<T extends z.ZodTypeAny> = T extends z.ZodDate ? st
|
|
|
255
255
|
type InferZodRelaxedDataSchema<T extends z.ZodObject<any>> = { [K in keyof T['shape']]: MapRelaxedZodSchemaField<T['shape'][K]>; };
|
|
256
256
|
//#endregion
|
|
257
257
|
//#region src/validation/zod/table-schema-zod.d.ts
|
|
258
|
-
type ZodSchemaSupportedTypes = z.ZodString | z.ZodNumber | z.ZodInt | z.ZodInt32 | z.ZodUInt32 | z.ZodBigInt | z.ZodBoolean | z.ZodDate | z.ZodISODateTime | z.ZodISOTime | z.ZodISODate | z.ZodEmail | z.ZodURL | z.ZodUUID | z.ZodCUID | z.ZodCUID2 | z.ZodULID | z.ZodEnum;
|
|
258
|
+
type ZodSchemaSupportedTypes = z.ZodString | z.ZodNumber | z.ZodInt | z.ZodInt32 | z.ZodUInt32 | z.ZodBigInt | z.ZodBoolean | z.ZodDate | z.ZodISODateTime | z.ZodISOTime | z.ZodISODate | z.ZodEmail | z.ZodURL | z.ZodUUID | z.ZodCUID | z.ZodCUID2 | z.ZodULID | z.ZodEnum | z.ZodArray;
|
|
259
259
|
type TableSchemaZod = z.ZodObject<Record<string, ZodSchemaSupportedTypes | z.ZodNullable<ZodSchemaSupportedTypes> | z.ZodCodec | z.ZodNullable<z.ZodCodec>>>;
|
|
260
260
|
//#endregion
|
|
261
261
|
export { duckDsnZodSchema as a, assertValidTableName as c, duckConnectionParamsZodSchema as d, duckValidatorsZod as i, DuckConnectionParams as l, InferZodRelaxedDataSchema as n, assertValidAliasName as o, ensureZodTableSchema as r, assertValidSchemaName as s, TableSchemaZod as t, duckAllConnectionOptionsZodSchema as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as DuckConnectionParams, n as InferZodRelaxedDataSchema, t as TableSchemaZod } from "./index-
|
|
2
|
-
import { DuckDBConnection, DuckDBType } from "@duckdb/node-api";
|
|
1
|
+
import { l as DuckConnectionParams, n as InferZodRelaxedDataSchema, t as TableSchemaZod } from "./index-Z9LfGsCV.mjs";
|
|
2
|
+
import { DuckDBConnection, DuckDBDecimalType, DuckDBListType, DuckDBType } from "@duckdb/node-api";
|
|
3
3
|
import { Logger } from "@logtape/logtape";
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { ZodObject } from "zod";
|
|
@@ -91,6 +91,8 @@ type GetTableCreateFromZodParams<TSchema extends TableSchemaZod> = {
|
|
|
91
91
|
schema: TSchema;
|
|
92
92
|
options?: TableCreateOptions;
|
|
93
93
|
};
|
|
94
|
+
declare const duckDbTypes: [["VARCHAR", import("@duckdb/node-api").DuckDBVarCharType], ["BIGINT", import("@duckdb/node-api").DuckDBBigIntType], ["UBIGINT", import("@duckdb/node-api").DuckDBUBigIntType], ["HUGEINT", import("@duckdb/node-api").DuckDBHugeIntType], ["TIMESTAMP", import("@duckdb/node-api").DuckDBTimestampType], ["TIMESTAMP_MS", import("@duckdb/node-api").DuckDBTimestampMillisecondsType], ["UUID", import("@duckdb/node-api").DuckDBUUIDType], ["BOOLEAN", import("@duckdb/node-api").DuckDBBooleanType], ["INTEGER", import("@duckdb/node-api").DuckDBIntegerType], ["DOUBLE", import("@duckdb/node-api").DuckDBDoubleType], ["FLOAT", import("@duckdb/node-api").DuckDBFloatType], ["DATE", import("@duckdb/node-api").DuckDBDateType], ["DECIMAL", DuckDBDecimalType], ["VARCHAR[]", DuckDBListType], ["INTEGER[]", DuckDBListType], ["BOOLEAN[]", DuckDBListType], ["BIGINT[]", DuckDBListType], ["UBIGINT[]", DuckDBListType], ["UUID[]", DuckDBListType], ["DATE[]", DuckDBListType], ["TIMESTAMP[]", DuckDBListType], ["TIMESTAMP_MS[]", DuckDBListType], ["DOUBLE[]", DuckDBListType], ["FLOAT[]", DuckDBListType]];
|
|
95
|
+
type SupportedCustomDuckDbTypes = (typeof duckDbTypes)[number][0];
|
|
94
96
|
declare const getTableCreateFromZod: <TSchema extends TableSchemaZod>(params: GetTableCreateFromZodParams<TSchema>) => TableCreateFromZodResult<TSchema>;
|
|
95
97
|
//#endregion
|
|
96
98
|
//#region src/sql-duck.d.ts
|
|
@@ -381,6 +383,14 @@ declare class DuckDatabaseManager {
|
|
|
381
383
|
analyze: () => Promise<boolean>;
|
|
382
384
|
checkpoint: (dbAlias: string) => Promise<boolean>;
|
|
383
385
|
vacuum: () => Promise<boolean>;
|
|
386
|
+
getCurrentDatabase: () => Promise<string | null>;
|
|
387
|
+
getCurrentSchema: () => Promise<string | null>;
|
|
388
|
+
getCurrentCatalog: () => Promise<string | null>;
|
|
389
|
+
/**
|
|
390
|
+
* Set the default database to use
|
|
391
|
+
* @throws if the database alias does not exist
|
|
392
|
+
*/
|
|
393
|
+
use: (dbAlias: string) => Promise<true>;
|
|
384
394
|
/**
|
|
385
395
|
* Helper to create an initial database file.
|
|
386
396
|
*/
|
|
@@ -430,4 +440,4 @@ declare const flowbladeLogtapeSqlduckConfig: {
|
|
|
430
440
|
//#region src/logger/sqlduck-default-logtape-logger.d.ts
|
|
431
441
|
declare const sqlduckDefaultLogtapeLogger: import("@logtape/logtape").Logger;
|
|
432
442
|
//#endregion
|
|
433
|
-
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 };
|
|
443
|
+
export { Database, type DuckConnectionParams, DuckDatabaseManager, DuckExtensionsManager, DuckMemory, type DuckMemoryTag, DuckSettingsManager, type DuckdbReservedKeywords, type OnChunkAppendedCb, type OnChunkAppendedStats, SqlDuck, type SqlDuckParams, type SupportedCustomDuckDbTypes, Table, type ToTableParams, duckReservedKeywords, flowbladeLogtapeSqlduckConfig, getTableCreateFromZod, sqlduckDefaultLogtapeLogger, zodCodecs };
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as sqlduckDefaultLogtapeLogger, r as flowbladeLogtapeSqlduckConfig, t as FileSystemUtils } from "./file-system-utils-DT6smf4C.mjs";
|
|
2
2
|
import { t as duckReservedKeywords } from "./duck-reserved-keywords-BzYA7jvN.mjs";
|
|
3
3
|
import { c as duckValidatorsZod, r as assertValidAliasName, s as duckConnectionParamsZodSchema } from "./zod-DB5FHzXW.mjs";
|
|
4
|
-
import { BIGINT, BOOLEAN, DATE, DECIMAL, DOUBLE, DuckDBDataChunk, DuckDBDateValue, DuckDBDecimalType, DuckDBDecimalValue, DuckDBInstanceCache, DuckDBTimestampMillisecondsValue, DuckDBTypeId, ENUM, FLOAT, HUGEINT, INTEGER, SMALLINT, TIMESTAMP, TIMESTAMP_MS, TINYINT, UBIGINT, UHUGEINT, UINTEGER, USMALLINT, UTINYINT, UUID, VARCHAR } from "@duckdb/node-api";
|
|
4
|
+
import { BIGINT, BOOLEAN, DATE, DECIMAL, DOUBLE, DuckDBDataChunk, DuckDBDateValue, DuckDBDecimalType, DuckDBDecimalValue, DuckDBInstanceCache, DuckDBListType, DuckDBTimestampMillisecondsValue, DuckDBTypeId, ENUM, FLOAT, HUGEINT, INTEGER, LIST, SMALLINT, TIMESTAMP, TIMESTAMP_MS, TINYINT, UBIGINT, UHUGEINT, UINTEGER, USMALLINT, UTINYINT, UUID, VARCHAR } from "@duckdb/node-api";
|
|
5
5
|
import * as z from "zod";
|
|
6
6
|
import { assertNever } from "@httpx/assert";
|
|
7
7
|
import { isPlainObject } from "@httpx/plain-object";
|
|
@@ -425,22 +425,33 @@ var DuckDatabaseManager = class {
|
|
|
425
425
|
*/
|
|
426
426
|
attach = async (dbParams, options) => {
|
|
427
427
|
const params = duckConnectionParamsZodSchema.parse(dbParams);
|
|
428
|
-
const rawSql = new DuckDatabaseAttachCommand(params, options).getRawSql();
|
|
429
|
-
const
|
|
428
|
+
const rawSql = new DuckDatabaseAttachCommand(params, { behaviour: options?.behaviour }).getRawSql();
|
|
429
|
+
const restoreCurrentDb = await this.getCurrentDatabase();
|
|
430
|
+
const tempDbNameHack = "temp_run_detach_if_attached_hack_db";
|
|
431
|
+
let isTempDbNameHackCreated = false;
|
|
430
432
|
try {
|
|
431
|
-
await this.#executor.getRowObjectsJS([
|
|
432
|
-
`attach(${params.alias}`,
|
|
433
|
-
behaviour ?? null,
|
|
434
|
-
")"
|
|
435
|
-
].filter(Boolean).join(","), rawSql);
|
|
433
|
+
await this.#executor.getRowObjectsJS([`attach(${params.alias}`, options === void 0 ? null : JSON.stringify(options)].filter(Boolean).join(",") + ")", rawSql);
|
|
436
434
|
} catch (e) {
|
|
437
435
|
if (options?.behaviour === "OR REPLACE" && options?.runDetachIfAttachOrReplaceFailWithAlreadyAttached === true) {
|
|
438
436
|
const alreadyAttached = getAlreadyAttachedDatabaseFromError(e);
|
|
439
437
|
if (alreadyAttached.isAlreadyAttached === true) {
|
|
438
|
+
if (alreadyAttached.dbAlias === restoreCurrentDb) {
|
|
439
|
+
await this.attachIfNotExists({
|
|
440
|
+
type: "memory",
|
|
441
|
+
alias: tempDbNameHack
|
|
442
|
+
});
|
|
443
|
+
await this.use(tempDbNameHack);
|
|
444
|
+
isTempDbNameHackCreated = true;
|
|
445
|
+
}
|
|
440
446
|
await this.detachOrIgnore(alreadyAttached.dbAlias);
|
|
441
447
|
await this.attach(dbParams);
|
|
442
448
|
} else throw e;
|
|
443
449
|
} else throw e;
|
|
450
|
+
} finally {
|
|
451
|
+
if (restoreCurrentDb !== null && isTempDbNameHackCreated) {
|
|
452
|
+
await this.use(restoreCurrentDb);
|
|
453
|
+
await this.detachOrIgnore(tempDbNameHack);
|
|
454
|
+
}
|
|
444
455
|
}
|
|
445
456
|
return new Database({ alias: params.alias });
|
|
446
457
|
};
|
|
@@ -576,6 +587,24 @@ var DuckDatabaseManager = class {
|
|
|
576
587
|
await this.#executor.getRowObjectsJS("vacuum()", "VACUUM");
|
|
577
588
|
return true;
|
|
578
589
|
};
|
|
590
|
+
getCurrentDatabase = async () => {
|
|
591
|
+
return (await this.#executor.getRowObjectsJS("getCurrentDatabase()", "SELECT current_database() as current_database"))[0]?.current_database ?? null;
|
|
592
|
+
};
|
|
593
|
+
getCurrentSchema = async () => {
|
|
594
|
+
return (await this.#executor.getRowObjectsJS("getCurrentSchema()", "SELECT current_schema() as current_schema"))?.[0]?.current_schema ?? null;
|
|
595
|
+
};
|
|
596
|
+
getCurrentCatalog = async () => {
|
|
597
|
+
return (await this.#executor.getRowObjectsJS("getCurrentCatalog()", "SELECT current_catalog() as current_catalog"))?.[0]?.current_catalog ?? null;
|
|
598
|
+
};
|
|
599
|
+
/**
|
|
600
|
+
* Set the default database to use
|
|
601
|
+
* @throws if the database alias does not exist
|
|
602
|
+
*/
|
|
603
|
+
use = async (dbAlias) => {
|
|
604
|
+
const safeAlias = duckValidatorsZod.aliasName.parse(dbAlias);
|
|
605
|
+
await this.#executor.getRowObjectsJS(`use(${safeAlias})`, `USE ${safeAlias}`);
|
|
606
|
+
return true;
|
|
607
|
+
};
|
|
579
608
|
/**
|
|
580
609
|
* Helper to create an initial database file.
|
|
581
610
|
*/
|
|
@@ -664,7 +693,18 @@ const duckDbTypes = [
|
|
|
664
693
|
["DOUBLE", DOUBLE],
|
|
665
694
|
["FLOAT", FLOAT],
|
|
666
695
|
["DATE", DATE],
|
|
667
|
-
["DECIMAL", new DuckDBDecimalType(18, 3)]
|
|
696
|
+
["DECIMAL", new DuckDBDecimalType(18, 3)],
|
|
697
|
+
["VARCHAR[]", new DuckDBListType(VARCHAR)],
|
|
698
|
+
["INTEGER[]", new DuckDBListType(INTEGER)],
|
|
699
|
+
["BOOLEAN[]", new DuckDBListType(BOOLEAN)],
|
|
700
|
+
["BIGINT[]", new DuckDBListType(BIGINT)],
|
|
701
|
+
["UBIGINT[]", new DuckDBListType(UBIGINT)],
|
|
702
|
+
["UUID[]", new DuckDBListType(UUID)],
|
|
703
|
+
["DATE[]", new DuckDBListType(DATE)],
|
|
704
|
+
["TIMESTAMP[]", new DuckDBListType(TIMESTAMP)],
|
|
705
|
+
["TIMESTAMP_MS[]", new DuckDBListType(TIMESTAMP_MS)],
|
|
706
|
+
["DOUBLE[]", new DuckDBListType(DOUBLE)],
|
|
707
|
+
["FLOAT[]", new DuckDBListType(FLOAT)]
|
|
668
708
|
];
|
|
669
709
|
const duckDbTypesMap = new Map(duckDbTypes);
|
|
670
710
|
const getTableCreateFromZod = (params) => {
|
|
@@ -681,8 +721,23 @@ const getTableCreateFromZod = (params) => {
|
|
|
681
721
|
for (const [columnName, def] of Object.entries(json.properties)) {
|
|
682
722
|
const { type, duckdbType, nullable, format, primaryKey, minimum, maximum, multipleOf } = def;
|
|
683
723
|
const c = { name: columnName };
|
|
684
|
-
if (duckdbType !== void 0 && duckDbTypesMap.has(duckdbType))
|
|
685
|
-
|
|
724
|
+
if (duckdbType !== void 0 && !duckDbTypesMap.has(duckdbType)) throw new Error(`The provided "duckdbType: '${duckdbType}'" for '${columnName}' isn't currently supported - ${JSON.stringify(def)}`);
|
|
725
|
+
const customDuckDbType = duckdbType === void 0 ? void 0 : duckDbTypesMap.get(duckdbType);
|
|
726
|
+
if (customDuckDbType === void 0) switch (type) {
|
|
727
|
+
case "array":
|
|
728
|
+
switch (def?.items?.type) {
|
|
729
|
+
case "string":
|
|
730
|
+
c.duckdbType = LIST(VARCHAR);
|
|
731
|
+
break;
|
|
732
|
+
case "number":
|
|
733
|
+
c.duckdbType = LIST(INTEGER);
|
|
734
|
+
break;
|
|
735
|
+
case "boolean":
|
|
736
|
+
c.duckdbType = LIST(BOOLEAN);
|
|
737
|
+
break;
|
|
738
|
+
default: throw new Error(`The inferred duckdb array for '${columnName}' is not supported - ${JSON.stringify(def)}`);
|
|
739
|
+
}
|
|
740
|
+
break;
|
|
686
741
|
case "string":
|
|
687
742
|
if (Array.isArray(def.enum)) c.duckdbType = ENUM(def.enum);
|
|
688
743
|
else switch (format) {
|
|
@@ -719,6 +774,7 @@ const getTableCreateFromZod = (params) => {
|
|
|
719
774
|
break;
|
|
720
775
|
default: throw new Error(`Cannot guess '${columnName}' type - ${JSON.stringify(def)}`);
|
|
721
776
|
}
|
|
777
|
+
else c.duckdbType = customDuckDbType;
|
|
722
778
|
if (primaryKey === true) c.constraint = "PRIMARY KEY";
|
|
723
779
|
else if (nullable !== true) c.constraint = "NOT NULL";
|
|
724
780
|
columnTypesMap.set(columnName, c.duckdbType);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as duckDsnZodSchema, c as assertValidTableName, d as duckConnectionParamsZodSchema, i as duckValidatorsZod, n as InferZodRelaxedDataSchema, o as assertValidAliasName, r as ensureZodTableSchema, s as assertValidSchemaName, t as TableSchemaZod, u as duckAllConnectionOptionsZodSchema } from "../../index-
|
|
1
|
+
import { a as duckDsnZodSchema, c as assertValidTableName, d as duckConnectionParamsZodSchema, i as duckValidatorsZod, n as InferZodRelaxedDataSchema, o as assertValidAliasName, r as ensureZodTableSchema, s as assertValidSchemaName, t as TableSchemaZod, u as duckAllConnectionOptionsZodSchema } from "../../index-Z9LfGsCV.mjs";
|
|
2
2
|
export { type InferZodRelaxedDataSchema, type TableSchemaZod, assertValidAliasName, assertValidSchemaName, assertValidTableName, duckAllConnectionOptionsZodSchema, duckConnectionParamsZodSchema, duckDsnZodSchema, duckValidatorsZod, ensureZodTableSchema };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowblade/sqlduck",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"exports": {
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"@belgattitude/eslint-config-bases": "8.19.1",
|
|
96
96
|
"@dotenvx/dotenvx": "2.21.0",
|
|
97
97
|
"@duckdb/node-api": "1.5.5-r.4",
|
|
98
|
-
"@faker-js/faker": "10.
|
|
98
|
+
"@faker-js/faker": "10.6.0",
|
|
99
99
|
"@flowblade/source-kysely": "^1.7.0",
|
|
100
100
|
"@httpx/assert": "0.18.0",
|
|
101
101
|
"@mitata/counters": "0.0.8",
|