From 9be23ba02d8762bb65b5affc2fa5eabf1066e416 Mon Sep 17 00:00:00 2001 From: kilisei Date: Fri, 28 Nov 2025 14:49:05 +0100 Subject: [PATCH 1/3] feat(drizzle): support date types --- src/integrations/drizzle/_session.ts | 23 +++++++++++++++++++---- test/integrations/drizzle.test.ts | 17 ++++++++++++++++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/integrations/drizzle/_session.ts b/src/integrations/drizzle/_session.ts index dcd005f..65f509a 100644 --- a/src/integrations/drizzle/_session.ts +++ b/src/integrations/drizzle/_session.ts @@ -5,6 +5,7 @@ import { type TablesRelationalConfig, entityKind, NoopLogger, + type AnyColumn, } from "drizzle-orm"; import { @@ -21,6 +22,7 @@ import type { } 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 @@ -95,6 +97,7 @@ export class DB0PreparedQuery< values: T["values"]; execute: T["execute"]; }> { + fields?: SelectedFieldsOrdered; constructor( private stmt: Statement, query: Query, @@ -104,18 +107,30 @@ export class DB0PreparedQuery< 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[])); + + 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[])); + + 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`; }); From b91fd131057c6e86b70d940a5fc2cc959f357787 Mon Sep 17 00:00:00 2001 From: kilisei Date: Fri, 28 Nov 2025 15:09:05 +0100 Subject: [PATCH 2/3] chore: return raw row if no fields are provided --- src/integrations/drizzle/_session.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/integrations/drizzle/_session.ts b/src/integrations/drizzle/_session.ts index 65f509a..3df61e0 100644 --- a/src/integrations/drizzle/_session.ts +++ b/src/integrations/drizzle/_session.ts @@ -6,6 +6,7 @@ import { entityKind, NoopLogger, type AnyColumn, + type SelectedFieldsOrdered } from "drizzle-orm"; import { @@ -16,7 +17,6 @@ import { import type { PreparedQueryConfig, - SelectedFieldsOrdered, SQLiteExecuteMethod, SQLiteTransactionConfig, } from "drizzle-orm/sqlite-core"; @@ -51,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 { @@ -98,11 +98,12 @@ export class DB0PreparedQuery< 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, ) { @@ -117,7 +118,11 @@ export class DB0PreparedQuery< async all(): Promise { const rows = await this.stmt.all(...(this.query.params as any[])); - return rows.map((row) => { + if (!this.fields) { + return rows + } + + return rows.map(row => { const rowArray = this.fields.map(({ field }) => row[field.name]); return mapResultRow(this.fields, rowArray, undefined); }); @@ -126,6 +131,10 @@ export class DB0PreparedQuery< 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]), From ff9cbda411228fc73f9f73d4538a8fa76dbb4b30 Mon Sep 17 00:00:00 2001 From: kilisei Date: Mon, 1 Dec 2025 15:33:00 +0100 Subject: [PATCH 3/3] chore(drizzle): format --- src/integrations/drizzle/_session.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/integrations/drizzle/_session.ts b/src/integrations/drizzle/_session.ts index 3df61e0..a6e7d04 100644 --- a/src/integrations/drizzle/_session.ts +++ b/src/integrations/drizzle/_session.ts @@ -6,7 +6,7 @@ import { entityKind, NoopLogger, type AnyColumn, - type SelectedFieldsOrdered + type SelectedFieldsOrdered, } from "drizzle-orm"; import { @@ -119,10 +119,10 @@ export class DB0PreparedQuery< const rows = await this.stmt.all(...(this.query.params as any[])); if (!this.fields) { - return rows + return rows; } - return rows.map(row => { + return rows.map((row) => { const rowArray = this.fields.map(({ field }) => row[field.name]); return mapResultRow(this.fields, rowArray, undefined); }); @@ -132,7 +132,7 @@ export class DB0PreparedQuery< const row = await this.stmt.get(...(this.query.params as any[])); if (!this.fields) { - return row + return row; } return mapResultRow(