@happyvertical/sql 0.102.4 → 0.102.5

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.
Files changed (30) hide show
  1. package/README.md +26 -0
  2. package/dist/chunks/{duckdb-LMyfKZGi.js → duckdb-c4vdDzPL.js} +5 -4
  3. package/dist/chunks/{duckdb-LMyfKZGi.js.map → duckdb-c4vdDzPL.js.map} +1 -1
  4. package/dist/chunks/duckdb-resources-DBlvosDo.js +44 -0
  5. package/dist/chunks/duckdb-resources-DBlvosDo.js.map +1 -0
  6. package/dist/chunks/{postgres-dialect-Bfswr4Vs.js → postgres-dialect-CGv6DxSP.js} +3 -775
  7. package/dist/chunks/postgres-dialect-CGv6DxSP.js.map +1 -0
  8. package/dist/chunks/query-RzXJ4B9s.js +353 -0
  9. package/dist/chunks/query-RzXJ4B9s.js.map +1 -0
  10. package/dist/chunks/schema-manager-cxsySSDA.js +777 -0
  11. package/dist/chunks/schema-manager-cxsySSDA.js.map +1 -0
  12. package/dist/chunks/{sqlite-connection-cache-ChWav9iY.js → sqlite-connection-cache-CYThh9l5.js} +2 -2
  13. package/dist/chunks/{sqlite-connection-cache-ChWav9iY.js.map → sqlite-connection-cache-CYThh9l5.js.map} +1 -1
  14. package/dist/chunks/{sqlite-native--z4BnolL.js → sqlite-native-CsJ_BLqN.js} +5 -4
  15. package/dist/chunks/{sqlite-native--z4BnolL.js.map → sqlite-native-CsJ_BLqN.js.map} +1 -1
  16. package/dist/chunks/{sqlite-0PMv1va2.js → sqlite-rILMdW7Z.js} +6 -5
  17. package/dist/chunks/{sqlite-0PMv1va2.js.map → sqlite-rILMdW7Z.js.map} +1 -1
  18. package/dist/index.d.ts +3 -45
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +6 -238
  21. package/dist/index.js.map +1 -1
  22. package/dist/pglite.js +2 -1
  23. package/dist/pglite.js.map +1 -1
  24. package/dist/query.d.ts +61 -0
  25. package/dist/query.d.ts.map +1 -0
  26. package/dist/query.js +3 -0
  27. package/package.json +6 -2
  28. package/dist/chunks/duckdb-resources-Cci6Lo6H.js +0 -156
  29. package/dist/chunks/duckdb-resources-Cci6Lo6H.js.map +0 -1
  30. package/dist/chunks/postgres-dialect-Bfswr4Vs.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -49,62 +49,20 @@ export type GetDatabaseOptions = (PostgresOptions & {
49
49
  * @throws Error if the database type is invalid
50
50
  */
51
51
  export declare function getDatabase(options?: GetDatabaseOptions | DatabaseInterface): Promise<DatabaseInterface>;
52
- /**
53
- * Synchronizes a SQL schema definition with a database
54
- * Creates tables if they don't exist and adds missing columns to existing tables
55
- *
56
- * @param options - Object containing database and schema
57
- * @param options.db - Database interface to use
58
- * @param options.schema - SQL schema definition
59
- * @throws Error if db or schema are missing or if the database doesn't support syncSchema
60
- */
61
- export declare function syncSchema(options: {
62
- db: DatabaseInterface;
63
- schema: string;
64
- }): Promise<void>;
65
- /**
66
- * Checks if a table exists in the database
67
- *
68
- * @param db - Database interface to use
69
- * @param tableName - Name of the table to check
70
- * @returns Promise resolving to boolean indicating if the table exists
71
- */
72
- export declare function tableExists(db: DatabaseInterface, tableName: string): Promise<boolean>;
73
- /**
74
- * Escapes and formats a value for use in SQL queries
75
- *
76
- * @param value - Value to escape
77
- * @returns String representation of the value safe for SQL use
78
- */
79
- export declare function escapeSqlValue(value: any): string;
80
- /**
81
- * Validates a column name for use in SQL queries
82
- *
83
- * @param column - Column name to validate
84
- * @returns The validated column name
85
- * @throws Error if the column name contains invalid characters
86
- */
87
- export declare function validateColumnName(column: string): string;
88
- import { buildWhere, formatDbError, raw } from "./shared/utils.js";
89
- export { type AggregateBuildResult, type AggregateFunction, type AggregateSelectExpr, type AggregateSpec, type AggregateTimeBucketUnit, bucketExpr, buildAggregate, } from './aggregate.js';
90
- export type { RawSqlKey, SqlAdapterType } from "./shared/utils.js";
91
- export { buildWhere, formatDbError, raw };
92
- import { convertUniqueIndexesToInlineConstraints } from "./shared/duckdb-schema-utils.js";
52
+ import { raw, syncSchema, tableExists } from './query.js';
93
53
  export { checkExpectedTables, checkRelationship, checkUniqueColumn, type DoctorCheck, type DoctorContext, type DoctorIssue, type DoctorLevel, type DoctorResult, type RelationshipSpec, type RunDoctorOptions, runDoctor, type UniqueColumnSpec, } from "./doctor.js";
94
54
  export { clearConnectionCache } from './json.js';
95
55
  export type { PGliteLike, PGliteOptions } from "./pglite.js";
96
56
  export { clearPostgresConnectionCache } from './postgres.js';
97
57
  export { assertCanExportDatabase, assertCanImportDatabase, type CreateDropOptions, createPostgresDatabase, type DumpOptions, databaseNameFromUrl, dropPostgresDatabase, dumpPostgresDatabase, isLocalDatabaseUrl, type PostgresImportLocalityOptions, type PostgresLocalityOptions, postgresEnvFromUrl, type RestoreOptions, redactDatabaseUrl, restorePostgresDatabase, } from "./postgres-cli.js";
98
- export type { SchemaInitializationResult } from "./schema-manager.js";
99
- export { DatabaseSchemaManager } from "./schema-manager.js";
58
+ export { type AggregateBuildResult, type AggregateFunction, type AggregateSelectExpr, type AggregateSpec, type AggregateTimeBucketUnit, bucketExpr, buildAggregate, buildWhere, convertUniqueIndexesToInlineConstraints, DatabaseSchemaManager, escapeSqlValue, formatDbError, type RawSqlKey, raw, type SchemaInitializationResult, type SqlAdapterType, syncSchema, tableExists, validateColumnName, } from './query.js';
100
59
  export * from "./shared/types.js";
101
60
  export type { SecureSqliteFileOptions, SqliteOptions } from './sqlite.js';
102
- export { convertUniqueIndexesToInlineConstraints };
103
61
  declare const _default: {
104
62
  getDatabase: typeof getDatabase;
105
63
  syncSchema: typeof syncSchema;
106
64
  tableExists: typeof tableExists;
107
- buildWhere: (where: import("./index.js").WhereClause, startIndex?: number, adapterType?: import("./index.js").SqlAdapterType) => {
65
+ buildWhere: (where: import("./query.js").WhereClause, startIndex?: number, adapterType?: import("./query.js").SqlAdapterType) => {
108
66
  sql: string;
109
67
  values: any[];
110
68
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAY,CAAC;AAClD,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,WAAW,EACZ,MAAM,mBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAU,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,CAAC,eAAe,GAAG;IAAE,IAAI,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC,GACzC,CAAC,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC,GACrC,CAAC,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC,GACrC,CAAC,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC,GACrC,WAAW,CAAC;AAmBhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,WAAW,CAC/B,OAAO,GAAE,kBAAkB,GAAG,iBAAsB,GACnD,OAAO,CAAC,iBAAiB,CAAC,CAqD5B;AAcD,OAAO,EAAc,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGtE,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,SAAS,EACT,KAAK,gBAAgB,GACtB,MAAM,aAAU,CAAC;AAElB,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAIjD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAU,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,sBAAsB,EACtB,KAAK,WAAW,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,KAAK,cAAc,EACnB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,mBAAgB,CAAC;AACxB,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,UAAU,EACV,cAAc,EACd,UAAU,EACV,uCAAuC,EACvC,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,KAAK,SAAS,EACd,GAAG,EACH,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EACnB,UAAU,EACV,WAAW,EACX,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,cAAc,mBAAgB,CAAC;AAC/B,YAAY,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;;;;;;;;;;;AAE1E,wBAME;AAEF,gBAAgB;AAChB,eAAO,MAAM,2BAA2B,OAAO,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
- import { C as parseConditionKey, D as wrapDatabaseError, E as unwrapRawKey, S as formatDbError, T as resolveInsertColumns, _ as validateColumnNames, a as createVectorCapabilities, b as DatabaseSchemaManager, c as createTransactionLock, d as validateDatabaseCacheOptions, f as escapeQuotedIdentifier, i as createTransactionErrorTracker, l as ConnectionCache, n as createGetTableSchema, o as normalizePostgresRawQuery, p as escapeStringLiteral, r as createPostgresDialect, t as createAlterTable, u as enableCachedValidation, w as raw, x as buildWhere } from "./chunks/postgres-dialect-Bfswr4Vs.js";
2
- import { n as throwWithDuckDBCleanup, r as convertUniqueIndexesToInlineConstraints, t as createDuckDBResourceCloser } from "./chunks/duckdb-resources-Cci6Lo6H.js";
1
+ import { a as raw, c as wrapDatabaseError, n as buildWhere, o as resolveInsertColumns, r as formatDbError, t as DatabaseSchemaManager } from "./chunks/schema-manager-cxsySSDA.js";
2
+ import { a as NestedTransactionError, c as bucketExpr, i as validateColumnName, l as buildAggregate, n as syncSchema, o as resolveSchemas, r as tableExists, s as convertUniqueIndexesToInlineConstraints, t as escapeSqlValue } from "./chunks/query-RzXJ4B9s.js";
3
3
  import { a as dropPostgresDatabase, c as postgresEnvFromUrl, i as databaseNameFromUrl, l as redactDatabaseUrl, n as assertCanImportDatabase, o as dumpPostgresDatabase, r as createPostgresDatabase, s as isLocalDatabaseUrl, t as assertCanExportDatabase, u as restorePostgresDatabase } from "./chunks/postgres-cli-DzZcXSIG.js";
4
+ import { _ as validateColumnNames, a as createVectorCapabilities, c as createTransactionLock, d as validateDatabaseCacheOptions, f as escapeQuotedIdentifier, i as createTransactionErrorTracker, l as ConnectionCache, n as createGetTableSchema, o as normalizePostgresRawQuery, p as escapeStringLiteral, r as createPostgresDialect, t as createAlterTable, u as enableCachedValidation } from "./chunks/postgres-dialect-CGv6DxSP.js";
5
+ import { n as throwWithDuckDBCleanup, t as createDuckDBResourceCloser } from "./chunks/duckdb-resources-DBlvosDo.js";
4
6
  import { t as redactDatabaseUrl$1 } from "./chunks/redact-database-url-CfMDvSdy.js";
5
7
  import { DatabaseError, loadEnvConfig } from "@happyvertical/utils";
6
8
  import { mkdir, readdir, stat } from "node:fs/promises";
@@ -20,149 +22,6 @@ var __exportAll = (all, no_symbols) => {
20
22
  return target;
21
23
  };
22
24
  //#endregion
23
- //#region src/aggregate.ts
24
- var VALID_DIRECTIONS = /* @__PURE__ */ new Set(["ASC", "DESC"]);
25
- var VALID_BUCKET_UNITS = /* @__PURE__ */ new Set([
26
- "minute",
27
- "hour",
28
- "day",
29
- "week",
30
- "month",
31
- "quarter",
32
- "year"
33
- ]);
34
- function validateSqlIdentifier(identifier) {
35
- if (typeof identifier !== "string" || !/^[a-zA-Z0-9_.]+$/.test(identifier)) throw new Error(`Invalid SQL identifier: ${identifier}`);
36
- return identifier;
37
- }
38
- function normalizeAdapter(adapterType) {
39
- return adapterType ?? "sqlite";
40
- }
41
- function placeholder(index) {
42
- return `$${index}`;
43
- }
44
- function bucketExpr(adapterType, unit, column) {
45
- if (!VALID_BUCKET_UNITS.has(unit)) throw new Error(`Invalid aggregate bucket unit: ${unit}`);
46
- const col = validateSqlIdentifier(column);
47
- const adapter = normalizeAdapter(adapterType);
48
- if (adapter === "postgres" || adapter === "duckdb" || adapter === "json") return `date_trunc('${unit}', ${col})`;
49
- switch (unit) {
50
- case "minute": return `strftime('%Y-%m-%d %H:%M:00', ${col})`;
51
- case "hour": return `strftime('%Y-%m-%d %H:00:00', ${col})`;
52
- case "day": return `strftime('%Y-%m-%d 00:00:00', ${col})`;
53
- case "week": return `strftime('%Y-%m-%d 00:00:00', date(${col}, printf('-%d days', (CAST(strftime('%w', ${col}) AS INTEGER) + 6) % 7)))`;
54
- case "month": return `strftime('%Y-%m-01 00:00:00', ${col})`;
55
- case "quarter": return `strftime('%Y-%m-%d 00:00:00', date(strftime('%Y-', ${col}) || printf('%02d', ((CAST(strftime('%m', ${col}) AS INTEGER) - 1) / 3) * 3 + 1) || '-01'))`;
56
- case "year": return `strftime('%Y-01-01 00:00:00', ${col})`;
57
- }
58
- }
59
- function aggregateExpression(expr) {
60
- const normalizedFn = String(expr.fn).toLowerCase();
61
- const fn = validateSqlIdentifier(String(expr.fn)).toUpperCase();
62
- if (normalizedFn === "count" && !expr.column) {
63
- if (expr.distinct) throw new Error(`Aggregate ${expr.fn} with distinct requires a column`);
64
- return "COUNT(*)";
65
- }
66
- if (!expr.column) throw new Error(`Aggregate ${expr.fn} requires a column`);
67
- const col = validateSqlIdentifier(expr.column);
68
- return `${fn}(${expr.distinct ? "DISTINCT " : ""}${col})`;
69
- }
70
- function selectExpression(expr, adapterType) {
71
- if ("column" in expr && !("fn" in expr) && !("bucket" in expr)) return {
72
- expression: validateSqlIdentifier(expr.column),
73
- alias: validateSqlIdentifier(expr.as ?? expr.column),
74
- groupingCandidate: true
75
- };
76
- if ("bucket" in expr) return {
77
- expression: bucketExpr(adapterType, expr.bucket, expr.column),
78
- alias: validateSqlIdentifier(expr.as),
79
- groupingCandidate: true
80
- };
81
- return {
82
- expression: aggregateExpression(expr),
83
- alias: validateSqlIdentifier(expr.as),
84
- groupingCandidate: false
85
- };
86
- }
87
- function expandHavingKey(key, expressionByAlias) {
88
- if (unwrapRawKey(key).isRaw) return key;
89
- const parsed = parseConditionKey(key);
90
- return raw(`${expressionByAlias.get(parsed.field) ?? validateSqlIdentifier(parsed.field)} ${parsed.operator}`);
91
- }
92
- function expandHaving(having, expressionByAlias) {
93
- const expandCondition = (condition) => Object.fromEntries(Object.entries(condition).map(([key, value]) => [expandHavingKey(key, expressionByAlias), value]));
94
- if (Array.isArray(having)) return having.map((andGroup) => andGroup.map((condition) => expandCondition(condition)));
95
- return expandCondition(having);
96
- }
97
- function buildHaving(having, expressionByAlias, startIndex, adapterType) {
98
- if (!having) return {
99
- sql: "",
100
- values: []
101
- };
102
- const built = buildWhere(expandHaving(having, expressionByAlias), startIndex, adapterType);
103
- return {
104
- sql: built.sql ? built.sql.replace(/^WHERE/, "HAVING") : "",
105
- values: built.values
106
- };
107
- }
108
- function buildOrderBy(orderBy) {
109
- if (!orderBy) return "";
110
- return `ORDER BY ${(Array.isArray(orderBy) ? orderBy : [orderBy]).map((item) => {
111
- const [field, direction = "ASC"] = item.trim().split(/\s+/);
112
- const normalizedDirection = direction.toUpperCase();
113
- if (!VALID_DIRECTIONS.has(normalizedDirection)) throw new Error(`Invalid aggregate order direction: ${direction}`);
114
- return `${validateSqlIdentifier(field)} ${normalizedDirection}`;
115
- }).join(", ")}`;
116
- }
117
- function buildAggregate(spec, startIndex = 1, adapterType) {
118
- const from = validateSqlIdentifier(spec.from);
119
- if (spec.select.length === 0) throw new Error("AggregateSpec.select must contain at least one expression");
120
- const expressionByAlias = /* @__PURE__ */ new Map();
121
- const groupingAliases = [];
122
- const selectSql = spec.select.map((expr) => {
123
- const selected = selectExpression(expr, adapterType);
124
- expressionByAlias.set(selected.alias, selected.expression);
125
- if (selected.groupingCandidate) groupingAliases.push(selected.alias);
126
- return `${selected.expression} AS ${selected.alias}`;
127
- });
128
- const where = spec.where ? buildWhere(spec.where, startIndex, adapterType) : {
129
- sql: "",
130
- values: []
131
- };
132
- let nextParamIndex = startIndex + where.values.length;
133
- const groupByItems = spec.groupBy ?? groupingAliases;
134
- const groupBySql = groupByItems.length > 0 ? `GROUP BY ${groupByItems.map((item) => expressionByAlias.has(item) ? expressionByAlias.get(item) : validateSqlIdentifier(item)).join(", ")}` : "";
135
- const having = buildHaving(spec.having, expressionByAlias, nextParamIndex, adapterType);
136
- nextParamIndex += having.values.length;
137
- const orderBySql = buildOrderBy(spec.orderBy);
138
- const pagingValues = [];
139
- const pagingSql = [];
140
- if (spec.limit !== void 0) {
141
- pagingSql.push(`LIMIT ${placeholder(nextParamIndex++)}`);
142
- pagingValues.push(spec.limit);
143
- } else if (spec.offset !== void 0 && normalizeAdapter(adapterType) === "sqlite") pagingSql.push("LIMIT -1");
144
- if (spec.offset !== void 0) {
145
- pagingSql.push(`OFFSET ${placeholder(nextParamIndex++)}`);
146
- pagingValues.push(spec.offset);
147
- }
148
- return {
149
- sql: [
150
- `SELECT ${selectSql.join(", ")}`,
151
- `FROM ${from}`,
152
- where.sql,
153
- groupBySql,
154
- having.sql,
155
- orderBySql,
156
- pagingSql.join(" ")
157
- ].filter(Boolean).join(" "),
158
- values: [
159
- ...where.values,
160
- ...having.values,
161
- ...pagingValues
162
- ]
163
- };
164
- }
165
- //#endregion
166
25
  //#region src/doctor.ts
167
26
  /**
168
27
  * Database integrity-check framework.
@@ -298,48 +157,6 @@ function countValueFromRow(value) {
298
157
  return "0";
299
158
  }
300
159
  //#endregion
301
- //#region src/shared/types.ts
302
- /**
303
- * Error thrown when `transaction()` is called on a transaction-scoped interface
304
- * belonging to an adapter whose engine has no savepoints.
305
- *
306
- * DuckDB — and therefore the JSON adapter built on it — does not implement
307
- * `SAVEPOINT`, so there is no way to re-enter the current transaction. Adapters
308
- * that can re-enter (PostgreSQL, SQLite) do so under a savepoint and never
309
- * throw this.
310
- *
311
- * The alternative would be to open a second, independent transaction, which is
312
- * what these adapters used to do; on a shared connection that silently
313
- * destroyed the enclosing transaction's uncommitted work.
314
- *
315
- * @example Ensuring a helper works on every adapter
316
- * ```typescript
317
- * // Take the transaction as a parameter rather than opening a nested one.
318
- * async function recordClick(db: DatabaseInterface, id: string) {
319
- * await db.update('links', { id }, { clicks: 1 });
320
- * }
321
- * await db.transaction(async (tx) => recordClick(tx, id));
322
- * ```
323
- */
324
- var NestedTransactionError = class extends DatabaseError {
325
- constructor(message, context) {
326
- super(message, context);
327
- this.name = "NestedTransactionError";
328
- }
329
- };
330
- /**
331
- * Resolves a SchemasOption to its concrete value.
332
- *
333
- * Adapters that need schemas (JSON, DuckDB) call this to unwrap the
334
- * lazy function. Adapters that don't (Postgres, SQLite) simply ignore
335
- * the `schemas` option without calling this.
336
- */
337
- function resolveSchemas(schemas) {
338
- if (!schemas) return void 0;
339
- if (typeof schemas === "function") return schemas();
340
- return schemas;
341
- }
342
- //#endregion
343
160
  //#region src/json.ts
344
161
  var json_exports = /* @__PURE__ */ __exportAll({
345
162
  clearConnectionCache: () => clearConnectionCache,
@@ -2550,60 +2367,11 @@ async function getDatabase(options = {}) {
2550
2367
  if (!options.type && (options.url?.startsWith("file:") || options.url === ":memory:")) options.type = "sqlite";
2551
2368
  if (options.type === "postgres") return (await Promise.resolve().then(() => postgres_exports)).getDatabase(options);
2552
2369
  if (options.type === "pglite") return (await import("./pglite.js")).getDatabase(options);
2553
- if (options.type === "sqlite") return (await import("./chunks/sqlite-0PMv1va2.js")).getDatabase(options);
2554
- if (options.type === "duckdb") return (await import("./chunks/duckdb-LMyfKZGi.js")).getDatabase(options);
2370
+ if (options.type === "sqlite") return (await import("./chunks/sqlite-rILMdW7Z.js")).getDatabase(options);
2371
+ if (options.type === "duckdb") return (await import("./chunks/duckdb-c4vdDzPL.js")).getDatabase(options);
2555
2372
  if (options.type === "json") return (await Promise.resolve().then(() => json_exports)).getDatabase(options);
2556
2373
  throw new Error("Invalid database type");
2557
2374
  }
2558
- /**
2559
- * Synchronizes a SQL schema definition with a database
2560
- * Creates tables if they don't exist and adds missing columns to existing tables
2561
- *
2562
- * @param options - Object containing database and schema
2563
- * @param options.db - Database interface to use
2564
- * @param options.schema - SQL schema definition
2565
- * @throws Error if db or schema are missing or if the database doesn't support syncSchema
2566
- */
2567
- async function syncSchema(options) {
2568
- const { db, schema } = options;
2569
- if (!db || !schema) throw new Error("db and schema are required");
2570
- if (db.syncSchema) await db.syncSchema(schema);
2571
- else throw new Error("Database adapter does not support schema synchronization");
2572
- }
2573
- /**
2574
- * Checks if a table exists in the database
2575
- *
2576
- * @param db - Database interface to use
2577
- * @param tableName - Name of the table to check
2578
- * @returns Promise resolving to boolean indicating if the table exists
2579
- */
2580
- async function tableExists(db, tableName) {
2581
- return db.tableExists(tableName);
2582
- }
2583
- /**
2584
- * Escapes and formats a value for use in SQL queries
2585
- *
2586
- * @param value - Value to escape
2587
- * @returns String representation of the value safe for SQL use
2588
- */
2589
- function escapeSqlValue(value) {
2590
- if (value === null) return "NULL";
2591
- if (value instanceof Date) return `'${value.toISOString()}'`;
2592
- if (typeof value === "number") return value.toString();
2593
- if (typeof value === "boolean") return value ? "1" : "0";
2594
- return `'${String(value).replace(/'/g, "''")}'`;
2595
- }
2596
- /**
2597
- * Validates a column name for use in SQL queries
2598
- *
2599
- * @param column - Column name to validate
2600
- * @returns The validated column name
2601
- * @throws Error if the column name contains invalid characters
2602
- */
2603
- function validateColumnName(column) {
2604
- if (typeof column !== "string" || !/^[a-zA-Z0-9_.]+$/.test(column)) throw new Error(`Invalid column name: ${column}`);
2605
- return column;
2606
- }
2607
2375
  var src_default = {
2608
2376
  getDatabase,
2609
2377
  syncSchema,