effect-sql-kysely
Version:
`effect-sql-kysely` is an full-featured integration between `@effect/sql` and `Kysely`.
79 lines (65 loc) • 2.21 kB
text/typescript
import { describe, expect, it } from "@effect/vitest";
import { Effect, Option } from "effect";
import * as Database from "../src/Sqlite.js";
import { Generated, Table } from "../src/Schema.js";
import * as Schema from "@effect/schema/Schema";
import * as kysely from "kysely";
import BetterSqlite3 from "better-sqlite3";
describe("database", () => {
class Users extends Table({
id: Generated(Schema.Int),
name: Schema.String,
}) { }
const TestSchema = Schema.Struct({
users: Users,
})
type TestSchema = typeof TestSchema.Encoded
class TestDatabase extends Database.make<TestSchema, TestDatabase>(
"TestDatabase"
) {}
const acquire = Effect.promise(async () => {
const db = new kysely.Kysely<TestSchema>({
dialect: new kysely.SqliteDialect({
database: new BetterSqlite3(":memory:"),
}),
});
await db.schema
.createTable("users")
.addColumn("id", "integer", (column) =>
column.primaryKey().autoIncrement()
)
.addColumn("name", "text")
.execute();
return db;
});
const createUser = TestDatabase.schema.single({
Request: Schema.String,
Result: Users.select,
execute: (db, name) =>
db.insertInto("users").values({ name }).returningAll(),
});
const findUser = TestDatabase.schema.findOne({
Request: Users.select.fields.id,
Result: Users.select,
execute: (db, id) =>
db.selectFrom("users").where("id", "=", id).selectAll(),
});
it.effect("should allow making SQL queries", () =>
Effect.gen(function* (_) {
const created = yield* createUser("Test");
const selected = yield* findUser(created.id);
expect(Option.some(created)).toEqual(selected);
}).pipe(Effect.provide(TestDatabase.layer({ acquire })), Effect.scoped)
);
it.effect("should allow making SQL queries with transactions", () =>
Effect.gen(function* (_) {
const created = yield* createUser("Test");
const selected = yield* findUser(created.id);
expect(Option.some(created)).toEqual(selected);
}).pipe(
TestDatabase.withTransaction,
Effect.provide(TestDatabase.layer({ acquire })),
Effect.scoped
)
);
});