{"version":3,"file":"d1-sqlite-dialect-sYHNqBte.mjs","names":["#config","#connection","#db","#d1"],"sources":["../src/d1-sqlite-dialect.ts"],"sourcesContent":["import type { D1Database } from \"@cloudflare/workers-types\";\nimport type {\n\tCompiledQuery,\n\tDatabaseConnection,\n\tDatabaseIntrospector,\n\tDatabaseMetadata,\n\tDatabaseMetadataOptions,\n\tDialect,\n\tDialectAdapter,\n\tDriver,\n\tKysely,\n\tQueryCompiler,\n\tQueryResult,\n\tSchemaMetadata,\n\tTableMetadata,\n} from \"kysely\";\nimport {\n\tDEFAULT_MIGRATION_LOCK_TABLE,\n\tDEFAULT_MIGRATION_TABLE,\n\tSqliteAdapter,\n\tSqliteQueryCompiler,\n} from \"kysely\";\n\nclass D1SqliteAdapter extends SqliteAdapter {}\n\n/**\n * Config for the D1 SQLite dialect.\n */\nexport interface D1SqliteDialectConfig {\n\t/**\n\t * A Cloudflare D1 database instance.\n\t */\n\tdatabase: D1Database;\n\n\t/**\n\t * Called once when the first query is executed.\n\t */\n\tonCreateConnection?:\n\t\t| ((connection: DatabaseConnection) => Promise<void>)\n\t\t| undefined;\n}\n\nclass D1SqliteDriver implements Driver {\n\treadonly #config: D1SqliteDialectConfig;\n\t#connection?: DatabaseConnection;\n\n\tconstructor(config: D1SqliteDialectConfig) {\n\t\tthis.#config = { ...config };\n\t}\n\n\tasync init(): Promise<void> {\n\t\tthis.#connection = new D1SqliteConnection(this.#config.database);\n\n\t\tif (this.#config.onCreateConnection) {\n\t\t\tawait this.#config.onCreateConnection(this.#connection);\n\t\t}\n\t}\n\n\tasync acquireConnection(): Promise<DatabaseConnection> {\n\t\treturn this.#connection!;\n\t}\n\n\tasync beginTransaction(): Promise<void> {\n\t\tthrow new Error(\n\t\t\t\"D1 does not support interactive transactions. Use the D1 batch() API instead.\",\n\t\t);\n\t}\n\n\tasync commitTransaction(): Promise<void> {\n\t\tthrow new Error(\n\t\t\t\"D1 does not support interactive transactions. Use the D1 batch() API instead.\",\n\t\t);\n\t}\n\n\tasync rollbackTransaction(): Promise<void> {\n\t\tthrow new Error(\n\t\t\t\"D1 does not support interactive transactions. Use the D1 batch() API instead.\",\n\t\t);\n\t}\n\n\tasync releaseConnection(): Promise<void> {}\n\n\tasync destroy(): Promise<void> {}\n}\n\nclass D1SqliteConnection implements DatabaseConnection {\n\treadonly #db: D1Database;\n\n\tconstructor(db: D1Database) {\n\t\tthis.#db = db;\n\t}\n\n\tasync executeQuery<O>(compiledQuery: CompiledQuery): Promise<QueryResult<O>> {\n\t\tconst results = await this.#db\n\t\t\t.prepare(compiledQuery.sql)\n\t\t\t.bind(...compiledQuery.parameters)\n\t\t\t.all();\n\n\t\tconst numAffectedRows =\n\t\t\tresults.meta.changes != null ? BigInt(results.meta.changes) : undefined;\n\n\t\treturn {\n\t\t\tinsertId:\n\t\t\t\tresults.meta.last_row_id === undefined ||\n\t\t\t\tresults.meta.last_row_id === null\n\t\t\t\t\t? undefined\n\t\t\t\t\t: BigInt(results.meta.last_row_id),\n\t\t\trows: (results?.results as O[]) || [],\n\t\t\tnumAffectedRows,\n\t\t\t// @ts-expect-error - deprecated in kysely >= 0.23, keep for backward compatibility\n\t\t\tnumUpdatedOrDeletedRows: numAffectedRows,\n\t\t};\n\t}\n\n\tasync *streamQuery<O>(): AsyncIterableIterator<QueryResult<O>> {\n\t\tthrow new Error(\"D1 does not support streaming queries.\");\n\t}\n}\n\nclass D1SqliteIntrospector implements DatabaseIntrospector {\n\treadonly #db: Kysely<unknown>;\n\treadonly #d1: D1Database;\n\n\tconstructor(db: Kysely<unknown>, d1: D1Database) {\n\t\tthis.#db = db;\n\t\tthis.#d1 = d1;\n\t}\n\n\tasync getSchemas(): Promise<SchemaMetadata[]> {\n\t\t// SQLite doesn't support schemas.\n\t\treturn [];\n\t}\n\n\tasync getTables(\n\t\toptions: DatabaseMetadataOptions = { withInternalKyselyTables: false },\n\t): Promise<TableMetadata[]> {\n\t\tlet query = this.#db\n\t\t\t// @ts-expect-error - sqlite_master is not in the schema\n\t\t\t.selectFrom(\"sqlite_master\")\n\t\t\t// @ts-expect-error\n\t\t\t.where(\"type\", \"in\", [\"table\", \"view\"])\n\t\t\t// @ts-expect-error\n\t\t\t.where(\"name\", \"not like\", \"sqlite_%\")\n\t\t\t// @ts-expect-error - D1 internal tables\n\t\t\t.where(\"name\", \"not like\", \"_cf_%\")\n\t\t\t.select([\"name\", \"type\", \"sql\"])\n\t\t\t.$castTo<{ name: string; type: string; sql: string | null }>();\n\n\t\tif (!options.withInternalKyselyTables) {\n\t\t\tquery = query\n\t\t\t\t// @ts-expect-error\n\t\t\t\t.where(\"name\", \"!=\", DEFAULT_MIGRATION_TABLE)\n\t\t\t\t// @ts-expect-error\n\t\t\t\t.where(\"name\", \"!=\", DEFAULT_MIGRATION_LOCK_TABLE);\n\t\t}\n\n\t\tconst tables = await query.execute();\n\n\t\tif (tables.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst statements = tables.map((table) =>\n\t\t\tthis.#d1.prepare(\"SELECT * FROM pragma_table_info(?)\").bind(table.name),\n\t\t);\n\t\tconst batchResults = await this.#d1.batch(statements);\n\n\t\treturn tables.map((table, index) => {\n\t\t\tconst columnInfo = (batchResults[index]?.results ?? []) as Array<{\n\t\t\t\tcid: number;\n\t\t\t\tname: string;\n\t\t\t\ttype: string;\n\t\t\t\tnotnull: number;\n\t\t\t\tdflt_value: string | null;\n\t\t\t\tpk: number;\n\t\t\t}>;\n\n\t\t\t// Find the column that has `autoincrement` from CREATE SQL\n\t\t\tlet autoIncrementCol = table.sql\n\t\t\t\t?.split(/[(),]/)\n\t\t\t\t?.find((it) => it.toLowerCase().includes(\"autoincrement\"))\n\t\t\t\t?.split(/\\s+/)\n\t\t\t\t?.filter(Boolean)?.[0]\n\t\t\t\t?.replace(/[\"`]/g, \"\");\n\n\t\t\t// In SQLite, `INTEGER PRIMARY KEY` is always an alias for rowid\n\t\t\t// and auto-increments even without the explicit AUTOINCREMENT keyword.\n\t\t\tif (!autoIncrementCol) {\n\t\t\t\tconst pkCols = columnInfo.filter((r) => r.pk > 0);\n\t\t\t\tconst singlePk = pkCols.length === 1 ? pkCols[0] : undefined;\n\t\t\t\tif (singlePk && singlePk.type.toLowerCase() === \"integer\") {\n\t\t\t\t\tautoIncrementCol = singlePk.name;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tname: table.name,\n\t\t\t\tisView: table.type === \"view\",\n\t\t\t\tcolumns: columnInfo.map((col) => ({\n\t\t\t\t\tname: col.name,\n\t\t\t\t\tdataType: col.type,\n\t\t\t\t\tisNullable: !col.notnull,\n\t\t\t\t\tisAutoIncrementing: col.name === autoIncrementCol,\n\t\t\t\t\thasDefaultValue: col.dflt_value != null,\n\t\t\t\t})),\n\t\t\t};\n\t\t});\n\t}\n\n\tasync getMetadata(\n\t\toptions?: DatabaseMetadataOptions,\n\t): Promise<DatabaseMetadata> {\n\t\treturn {\n\t\t\ttables: await this.getTables(options),\n\t\t};\n\t}\n}\n\nclass D1SqliteQueryCompiler extends SqliteQueryCompiler {}\n\nexport class D1SqliteDialect implements Dialect {\n\treadonly #config: D1SqliteDialectConfig;\n\n\tconstructor(config: D1SqliteDialectConfig) {\n\t\tthis.#config = { ...config };\n\t}\n\n\tcreateDriver(): Driver {\n\t\treturn new D1SqliteDriver(this.#config);\n\t}\n\n\tcreateQueryCompiler(): QueryCompiler {\n\t\treturn new D1SqliteQueryCompiler();\n\t}\n\n\tcreateAdapter(): DialectAdapter {\n\t\treturn new D1SqliteAdapter();\n\t}\n\n\tcreateIntrospector(db: Kysely<unknown>): DatabaseIntrospector {\n\t\treturn new D1SqliteIntrospector(db, this.#config.database);\n\t}\n}\n"],"mappings":"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"}