diff --git a/src/integrations/drizzle/_session.ts b/src/integrations/drizzle/_session.ts index dcd005f..a6e7d04 100644 --- a/src/integrations/drizzle/_session.ts +++ b/src/integrations/drizzle/_session.ts @@ -5,6 +5,8 @@ import { type TablesRelationalConfig, entityKind, NoopLogger, + type AnyColumn, + type SelectedFieldsOrdered, } from "drizzle-orm"; import { @@ -15,12 +17,12 @@ import { import type { PreparedQueryConfig, - SelectedFieldsOrdered, SQLiteExecuteMethod, SQLiteTransactionConfig, } from "drizzle-orm/sqlite-core"; import type { Database, Statement } from "db0"; +import { mapResultRow } from "./_utils.ts"; // Used as reference: https://github.com/drizzle-team/drizzle-orm/blob/main/drizzle-orm/src/d1/session.ts @@ -49,7 +51,7 @@ export class DB0Session< // @ts-expect-error TODO prepareQuery( query: Query, - fields: SelectedFieldsOrdered | undefined, + fields: SelectedFieldsOrdered | undefined, executeMethod: SQLiteExecuteMethod, customResultMapper?: (rows: unknown[][]) => unknown, ): DB0PreparedQuery { @@ -95,27 +97,49 @@ export class DB0PreparedQuery< values: T["values"]; execute: T["execute"]; }> { + fields?: SelectedFieldsOrdered; + constructor( private stmt: Statement, query: Query, private logger: Logger, - fields: SelectedFieldsOrdered | undefined, + fields: SelectedFieldsOrdered | undefined, executeMethod: SQLiteExecuteMethod, customResultMapper?: (rows: unknown[][]) => unknown, ) { super("async", executeMethod, query); + this.fields = fields; } run(): Promise<{ success: boolean }> { return this.stmt.run(...(this.query.params as any[])); } - all(): Promise { - return this.stmt.all(...(this.query.params as any[])); + async all(): Promise { + const rows = await this.stmt.all(...(this.query.params as any[])); + + if (!this.fields) { + return rows; + } + + return rows.map((row) => { + const rowArray = this.fields.map(({ field }) => row[field.name]); + return mapResultRow(this.fields, rowArray, undefined); + }); } - get(): Promise { - return this.stmt.get(...(this.query.params as any[])); + async get(): Promise { + const row = await this.stmt.get(...(this.query.params as any[])); + + if (!this.fields) { + return row; + } + + return mapResultRow( + this.fields, + this.fields.map(({ field }) => row[field.name]), + undefined, + ); } values(): Promise { diff --git a/test/integrations/drizzle.test.ts b/test/integrations/drizzle.test.ts index 7f0711a..c14f49e 100644 --- a/test/integrations/drizzle.test.ts +++ b/test/integrations/drizzle.test.ts @@ -61,6 +61,7 @@ describe("integrations: drizzle: with schema parameter", () => { id: dSqlite.numeric("id"), name: dSqlite.text("name"), email: dSqlite.text("email"), + joinDate: dSqlite.integer({ mode: "timestamp" }), }); const schema = { users }; @@ -75,7 +76,8 @@ describe("integrations: drizzle: with schema parameter", () => { await db.sql`create table if not exists users_schema ( id integer primary key autoincrement, name text, - email text + email text, + joinDate integer )`; }); @@ -85,6 +87,7 @@ describe("integrations: drizzle: with schema parameter", () => { .values({ name: "Jane Doe", email: "jane@example.com", + joinDate: new Date("2025-01-30T12:00:00.000Z"), }) .returning(); @@ -101,6 +104,18 @@ describe("integrations: drizzle: with schema parameter", () => { expect(res[0].email).toBe("jane@example.com"); }); + it(".all() converts integers to dates", async () => { + const res = await drizzleDb.select().from(users).all(); + + expect(res[0].joinDate).toStrictEqual(new Date("2025-01-30T12:00:00.000Z")); + }); + + it(".get() converts integers to dates", async () => { + const res = await drizzleDb.select().from(users).get(); + + expect(res!.joinDate).toStrictEqual(new Date("2025-01-30T12:00:00.000Z")); + }); + afterAll(async () => { await db.sql`DROP TABLE IF EXISTS users_schema`; });