Skip to content

Commit 59d24d0

Browse files
mikearnalditim-smart
authored andcommitted
Support Drizzle Config (#4850)
1 parent 8421e6e commit 59d24d0

File tree

8 files changed

+128
-52
lines changed

8 files changed

+128
-52
lines changed

.changeset/early-shrimps-yawn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@effect/sql-drizzle": minor
3+
---
4+
5+
Support drizzle config

packages/sql-drizzle/src/Mysql.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ import { makeRemoteCallback, patch, registerDialect } from "./internal/patch.js"
1717
* @since 1.0.0
1818
* @category constructors
1919
*/
20-
export const make: Effect.Effect<MySqlRemoteDatabase, never, Client.SqlClient> = Effect.gen(function*() {
21-
const client = yield* Client.SqlClient
22-
const db = drizzle(yield* makeRemoteCallback)
23-
registerDialect((db as any).dialect, client)
24-
return db
25-
})
20+
export const make = <TSchema extends Record<string, unknown> = Record<string, never>>(
21+
config?: Omit<DrizzleConfig<TSchema>, "logger">
22+
): Effect.Effect<MySqlRemoteDatabase<TSchema>, never, Client.SqlClient> =>
23+
Effect.gen(function*() {
24+
const client = yield* Client.SqlClient
25+
const db = drizzle(yield* makeRemoteCallback, config)
26+
registerDialect((db as any).dialect, client)
27+
return db
28+
})
2629

2730
/**
2831
* @since 1.0.0
@@ -51,7 +54,7 @@ export class MysqlDrizzle extends Context.Tag("@effect/sql-drizzle/Mysql")<
5154
* @since 1.0.0
5255
* @category layers
5356
*/
54-
export const layer: Layer.Layer<MysqlDrizzle, never, Client.SqlClient> = Layer.effect(MysqlDrizzle, make)
57+
export const layer: Layer.Layer<MysqlDrizzle, never, Client.SqlClient> = Layer.effect(MysqlDrizzle, make())
5558

5659
/**
5760
* @since 1.0.0

packages/sql-drizzle/src/Pg.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ import { makeRemoteCallback, patch, registerDialect } from "./internal/patch.js"
1717
* @since 1.0.0
1818
* @category constructors
1919
*/
20-
export const make: Effect.Effect<PgRemoteDatabase, never, Client.SqlClient> = Effect.gen(function*() {
21-
const client = yield* Client.SqlClient
22-
const db = drizzle(yield* makeRemoteCallback)
23-
registerDialect((db as any).dialect, client)
24-
return db
25-
})
20+
export const make = <TSchema extends Record<string, unknown> = Record<string, never>>(
21+
config?: Omit<DrizzleConfig<TSchema>, "logger">
22+
): Effect.Effect<PgRemoteDatabase<TSchema>, never, Client.SqlClient> =>
23+
Effect.gen(function*() {
24+
const client = yield* Client.SqlClient
25+
const db = drizzle(yield* makeRemoteCallback, config)
26+
registerDialect((db as any).dialect, client)
27+
return db
28+
})
2629

2730
/**
2831
* @since 1.0.0
@@ -51,7 +54,7 @@ export class PgDrizzle extends Context.Tag("@effect/sql-drizzle/Pg")<
5154
* @since 1.0.0
5255
* @category layers
5356
*/
54-
export const layer: Layer.Layer<PgDrizzle, never, Client.SqlClient> = Layer.effect(PgDrizzle, make)
57+
export const layer: Layer.Layer<PgDrizzle, never, Client.SqlClient> = Layer.effect(PgDrizzle, make())
5558

5659
/**
5760
* @since 1.0.0

packages/sql-drizzle/src/Sqlite.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,21 @@ import { drizzle } from "drizzle-orm/sqlite-proxy"
1111
import * as Context from "effect/Context"
1212
import * as Effect from "effect/Effect"
1313
import * as Layer from "effect/Layer"
14-
import type { Scope } from "effect/Scope"
1514
import { makeRemoteCallback, patch, registerDialect } from "./internal/patch.js"
1615

1716
/**
1817
* @since 1.0.0
1918
* @category constructors
2019
*/
21-
export const make: Effect.Effect<SqliteRemoteDatabase, never, Client.SqlClient | Scope> = Effect.gen(function*() {
22-
const client = yield* Client.SqlClient
23-
const db = drizzle(yield* makeRemoteCallback)
24-
registerDialect((db as any).dialect, client)
25-
return db
26-
})
20+
export const make = <TSchema extends Record<string, unknown> = Record<string, never>>(
21+
config?: Omit<DrizzleConfig<TSchema>, "logger">
22+
): Effect.Effect<SqliteRemoteDatabase<TSchema>, never, Client.SqlClient> =>
23+
Effect.gen(function*() {
24+
const client = yield* Client.SqlClient
25+
const db = drizzle(yield* makeRemoteCallback, config)
26+
registerDialect((db as any).dialect, client)
27+
return db
28+
})
2729

2830
/**
2931
* @since 1.0.0
@@ -52,7 +54,7 @@ export class SqliteDrizzle extends Context.Tag("@effect/sql-drizzle/Sqlite")<
5254
* @since 1.0.0
5355
* @category layers
5456
*/
55-
export const layer: Layer.Layer<SqliteDrizzle, never, Client.SqlClient> = Layer.scoped(SqliteDrizzle, make)
57+
export const layer: Layer.Layer<SqliteDrizzle, never, Client.SqlClient> = Layer.scoped(SqliteDrizzle, make())
5658

5759
/**
5860
* @since 1.0.0

packages/sql-drizzle/src/internal/patch.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ const PatchProto = {
4848
}
4949
return Effect.map(
5050
statement.values,
51-
(rows) => rows.map((row) => mapResultRow(prepared.fields, row, prepared.joinsNotNullableMap))
51+
(rows) => {
52+
if (prepared.customResultMapper) {
53+
return prepared.customResultMapper(rows)
54+
}
55+
return rows.map((row) => mapResultRow(prepared.fields, row, prepared.joinsNotNullableMap))
56+
}
5257
)
5358
}
5459
}

packages/sql-drizzle/test/Mysql.test.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { SqlClient } from "@effect/sql"
2-
import { MysqlDrizzle } from "@effect/sql-drizzle/Mysql"
2+
import * as Mysql from "@effect/sql-drizzle/Mysql"
33
import { assert, describe, it } from "@effect/vitest"
44
import * as D from "drizzle-orm/mysql-core"
5-
import { Effect } from "effect"
5+
import { Effect, Layer } from "effect"
6+
import { MysqlContainer } from "./utils-mysql.js"
67
import { DrizzleMysqlLive } from "./utils.js"
78

89
const users = D.mysqlTable("users", {
@@ -11,11 +12,15 @@ const users = D.mysqlTable("users", {
1112
snakeCase: D.text("snake_case").notNull()
1213
})
1314

15+
class ORM extends Effect.Service<ORM>()("ORM", { effect: Mysql.make({ schema: { users } }) }) {
16+
static Client = this.Default.pipe(Layer.provideMerge(MysqlContainer.ClientLive))
17+
}
18+
1419
describe.sequential("Mysql", () => {
1520
it.effect("works", () =>
1621
Effect.gen(function*() {
1722
const sql = yield* SqlClient.SqlClient
18-
const db = yield* MysqlDrizzle
23+
const db = yield* Mysql.MysqlDrizzle
1924

2025
yield* sql`CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, snake_case TEXT NOT NULL)`
2126
yield* db.insert(users).values({ name: "Alice", snakeCase: "alice" })
@@ -26,10 +31,24 @@ describe.sequential("Mysql", () => {
2631
Effect.catchTag("ContainerError", () => Effect.void)
2732
), { timeout: 60000 })
2833

34+
it.effect("orm", () =>
35+
Effect.gen(function*() {
36+
const sql = yield* SqlClient.SqlClient
37+
const db = yield* ORM
38+
39+
yield* sql`CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, snake_case TEXT NOT NULL)`
40+
yield* db.insert(users).values({ name: "Alice", snakeCase: "alice" })
41+
const results = yield* db.query.users.findMany({ columns: { id: true, name: false, snakeCase: true } })
42+
assert.deepStrictEqual(results, [{ id: 1, snakeCase: "alice" }])
43+
}).pipe(
44+
Effect.provide(ORM.Client),
45+
Effect.catchTag("ContainerError", () => Effect.void)
46+
), { timeout: 60000 })
47+
2948
it.effect("remote callback", () =>
3049
Effect.gen(function*(_) {
3150
const sql = yield* SqlClient.SqlClient
32-
const db = yield* MysqlDrizzle
51+
const db = yield* Mysql.MysqlDrizzle
3352
yield* sql`CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, snake_case TEXT NOT NULL)`
3453
const rows = yield* Effect.promise(() =>
3554
db.insert(users).values({ name: "Alice", snakeCase: "snake" }).$returningId()
@@ -45,7 +64,7 @@ describe.sequential("Mysql", () => {
4564
it.effect("remote callback multiple values", () =>
4665
Effect.gen(function*(_) {
4766
const sql = yield* SqlClient.SqlClient
48-
const db = yield* MysqlDrizzle
67+
const db = yield* Mysql.MysqlDrizzle
4968
yield* sql`CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, snake_case TEXT NOT NULL)`
5069
const rows = yield* Effect.promise(() =>
5170
db.insert(users).values([

packages/sql-drizzle/test/Pg.test.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { SqlClient } from "@effect/sql"
2-
import { PgDrizzle } from "@effect/sql-drizzle/Pg"
2+
import * as Pg from "@effect/sql-drizzle/Pg"
33
import { assert, describe, it } from "@effect/vitest"
44
import * as D from "drizzle-orm/pg-core"
5-
import { Effect } from "effect"
5+
import { Effect, Layer } from "effect"
6+
import { PgContainer } from "./utils-pg.js"
67
import { DrizzlePgLive } from "./utils.js"
78

89
const users = D.pgTable("users", {
@@ -11,11 +12,15 @@ const users = D.pgTable("users", {
1112
snakeCase: D.text("snake_case").notNull()
1213
})
1314

15+
class ORM extends Effect.Service<ORM>()("ORM", { effect: Pg.make({ schema: { users } }) }) {
16+
static Client = this.Default.pipe(Layer.provideMerge(PgContainer.ClientLive))
17+
}
18+
1419
describe.sequential("Pg", () => {
1520
it.effect("works", () =>
1621
Effect.gen(function*() {
1722
const sql = yield* SqlClient.SqlClient
18-
const db = yield* PgDrizzle
23+
const db = yield* Pg.PgDrizzle
1924

2025
yield* sql`CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, snake_case TEXT NOT NULL)`
2126
yield* db.insert(users).values({ name: "Alice", snakeCase: "alice" })
@@ -28,10 +33,26 @@ describe.sequential("Pg", () => {
2833
timeout: 60000
2934
})
3035

36+
it.effect("orm", () =>
37+
Effect.gen(function*() {
38+
const sql = yield* SqlClient.SqlClient
39+
const db = yield* ORM
40+
41+
yield* sql`CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, snake_case TEXT NOT NULL)`
42+
yield* db.insert(users).values({ name: "Alice", snakeCase: "alice" })
43+
const results = yield* db.query.users.findMany()
44+
assert.deepStrictEqual(results, [{ id: 1, name: "Alice", snakeCase: "alice" }])
45+
}).pipe(
46+
Effect.provide(ORM.Client),
47+
Effect.catchTag("ContainerError", () => Effect.void)
48+
), {
49+
timeout: 60000
50+
})
51+
3152
it.effect("remote callback", () =>
3253
Effect.gen(function*(_) {
3354
const sql = yield* SqlClient.SqlClient
34-
const db = yield* PgDrizzle
55+
const db = yield* Pg.PgDrizzle
3556
yield* sql`CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, snake_case TEXT NOT NULL)`
3657
yield* Effect.promise(() => db.insert(users).values({ name: "Alice", snakeCase: "snake" }))
3758
const results = yield* Effect.promise(() => db.select().from(users))

packages/sql-drizzle/test/Sqlite.test.ts

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,62 @@ import * as SqliteDrizzle from "@effect/sql-drizzle/Sqlite"
66
import { SqliteClient } from "@effect/sql-sqlite-node"
77
import { assert, describe, it } from "@effect/vitest"
88
import * as D from "drizzle-orm/sqlite-core"
9-
import { Effect } from "effect"
9+
import { Effect, Layer } from "effect"
1010

11-
const makeClient = Effect.gen(function*(_) {
12-
const fs = yield* _(FileSystem.FileSystem)
13-
const dir = yield* _(fs.makeTempDirectoryScoped())
14-
return yield* _(SqliteClient.make({
15-
filename: dir + "/test.db"
16-
}))
17-
}).pipe(Effect.provide([NodeFileSystem.layer, Reactivity.layer]))
11+
const SqlClientLive = Layer.scoped(
12+
SqlClient.SqlClient,
13+
Effect.gen(function*(_) {
14+
const fs = yield* _(FileSystem.FileSystem)
15+
const dir = yield* _(fs.makeTempDirectoryScoped())
16+
return yield* _(SqliteClient.make({
17+
filename: dir + "/test.db"
18+
}))
19+
})
20+
).pipe(
21+
Layer.provide(NodeFileSystem.layer),
22+
Layer.provide(Reactivity.layer)
23+
)
24+
25+
const SqliteDrizzleLive = SqliteDrizzle.layer.pipe(Layer.provideMerge(SqlClientLive))
1826

1927
const users = D.sqliteTable("users", {
2028
id: D.integer("id").primaryKey(),
2129
name: D.text("name"),
2230
snakeCase: D.text("snake_case")
2331
})
2432

33+
class ORM extends Effect.Service<ORM>()("ORM", { effect: SqliteDrizzle.make({ schema: { users } }) }) {
34+
static Client = this.Default.pipe(Layer.provideMerge(SqlClientLive))
35+
}
36+
2537
describe("SqliteDrizzle", () => {
26-
it.scoped("select", () =>
38+
it.effect("select", () =>
2739
Effect.gen(function*(_) {
28-
const sql = yield* _(makeClient)
29-
const db = yield* SqliteDrizzle.make.pipe(
30-
Effect.provideService(SqlClient.SqlClient, sql)
31-
)
40+
const sql = yield* SqlClient.SqlClient
41+
const db = yield* SqliteDrizzle.SqliteDrizzle
3242
yield* sql`CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, snake_case TEXT)`
3343
yield* db.insert(users).values({ name: "Alice", snakeCase: "snake" })
3444
const results = yield* db.select().from(users)
3545
assert.deepStrictEqual(results, [{ id: 1, name: "Alice", snakeCase: "snake" }])
36-
}))
46+
}).pipe(Effect.provide(SqliteDrizzleLive)))
47+
48+
it.effect("orm", () =>
49+
Effect.gen(function*(_) {
50+
const sql = yield* SqlClient.SqlClient
51+
const db = yield* ORM
52+
yield* sql`CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, snake_case TEXT)`
53+
yield* db.insert(users).values({ name: "Alice", snakeCase: "snake" })
54+
const results = yield* db.query.users.findMany()
55+
assert.deepStrictEqual(results, [{ id: 1, name: "Alice", snakeCase: "snake" }])
56+
}).pipe(Effect.provide(ORM.Client)))
3757

38-
it.scoped("remote callback", () =>
58+
it.effect("remote callback", () =>
3959
Effect.gen(function*(_) {
40-
const sql = yield* _(makeClient)
41-
const db = yield* SqliteDrizzle.make.pipe(
42-
Effect.provideService(SqlClient.SqlClient, sql)
43-
)
60+
const sql = yield* SqlClient.SqlClient
61+
const db = yield* SqliteDrizzle.SqliteDrizzle
4462
yield* sql`CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, snake_case TEXT)`
4563
yield* Effect.promise(() => db.insert(users).values({ name: "Alice", snakeCase: "snake" }))
4664
const results = yield* Effect.promise(() => db.select().from(users))
4765
assert.deepStrictEqual(results, [{ id: 1, name: "Alice", snakeCase: "snake" }])
48-
}))
66+
}).pipe(Effect.provide(SqliteDrizzleLive)))
4967
})

0 commit comments

Comments
 (0)