-
-
Notifications
You must be signed in to change notification settings - Fork 15
Description
In my schema/database management helper functions, I prefer to pass around instances of Db not OrchidORM<any> to reduce coupling.
However, when I call migrate() passing db.adapter, it blocks forever and never resolves. When I re-construct the ORM interface as { $qb: db, $adapter: db.adapter }, it works fine. Please check the reproduction below. Note that the bug only repeats inside a true (non-test) transaction.
At the very least, this needs to be fixed (either runtime or type-wise). Currently, db.adapter is an AdapterBase, which is what migrate() is supposed to accept.
Broader question is, why do we even need this type?
orchid-orm/packages/rake-db/src/utils.ts
Lines 3 to 8 in e7b1232
| export interface OrmParam { | |
| $qb: Query; | |
| $adapter: AdapterBase; | |
| } | |
| export type DbParam = OrmParam | AdapterBase; |
I propose to get rid of this 'pseudo ORM' interface object unless there is a clear reason to have it. I believe it's not used anywhere outside rake-db?
Reproduction (orchid-orm@1.62.3):
import type { Db } from "orchid-orm"
import { createBaseTable } from "orchid-orm"
import { makeRakeDbConfig, migrate } from "orchid-orm/migrations"
import { orchidORM } from "orchid-orm/postgres-js"
export const BaseTable = createBaseTable()
const db = orchidORM({ log: true }, {})
const rakeDbConfig = makeRakeDbConfig({
baseTable: BaseTable,
basePath: import.meta.url,
migrations: {
"0001_initial": async () => [],
},
migrationsTable: "rake_migration",
})
// I don't need full ORM in these functions so prefer to pass Db, not OrchidORM<any>
async function myMigrate(db: Db) {
await db.query`CREATE TABLE IF NOT EXISTS ${db.ref(rakeDbConfig.migrationsTable)} (version text NOT NULL, name text NOT NULL)`
console.log("calling migrate()")
// Below, migrate() will block forever.
// Replacing db.adapter with { $qb: db, $adapter: db.adapter } fixes blocking.
await migrate(db.adapter, { ...rakeDbConfig }).then(
() => console.log("migrate() completed"),
() => console.log("migrate() failed"),
)
}
async function main() {
// The issue only surfaces when using $transaction (and not testTransaction!).
await db.$transaction(async () => {
await myMigrate(db.$qb).then(
() => console.log("myMigrate() completed"),
() => console.log("myMigrate() failed"),
)
})
}
main()Result:
% dropdb is;createdb is; bun 1.ts
(34.1ms) BEGIN
(5.8ms) CREATE TABLE IF NOT EXISTS "rake_migration" (version text NOT NULL, name text NOT NULL)
calling migrate()
--- blocks forever until ^C
with db.adapter replaced with { $qb: db, $adapter: db.adapter }, it works correctly:
% dropdb is;createdb is; bun 1.ts
(31.5ms) BEGIN
(6.0ms) CREATE TABLE IF NOT EXISTS "rake_migration" (version text NOT NULL, name text NOT NULL)
calling migrate()
Migrating database undefined
Migrated file:///Users/is/test/0001_initial
migrate() completed
myMigrate() completed
(10.1ms) COMMIT