Skip to content

Commit 319eff6

Browse files
committed
feat: pg support
1 parent c0647d7 commit 319eff6

File tree

3 files changed

+93
-1
lines changed

3 files changed

+93
-1
lines changed

packages/drizzle-orm-browser-migrator/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
"types": "./dist/pglite/index.d.mts",
2525
"import": "./dist/pglite/index.mjs",
2626
"node": "./dist/pglite/index.mjs"
27+
},
28+
"./pg": {
29+
"types": "./dist/pg/index.d.mts",
30+
"import": "./dist/pg/index.mjs",
31+
"node": "./dist/pg/index.mjs"
2732
}
2833
},
2934
"main": "./dist/index.mjs",
@@ -44,7 +49,7 @@
4449
"attw": "attw --pack . --profile esm-only --ignore-rules cjs-resolves-to-esm"
4550
},
4651
"peerDependencies": {
47-
"drizzle-orm": ">=0.40.0"
52+
"drizzle-orm": ">=0.44.0"
4853
},
4954
"dependencies": {
5055
"@guiiai/logg": "^1.0.10"
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
2+
3+
import { Format, useLogg } from '@guiiai/logg'
4+
import { sql } from 'drizzle-orm'
5+
6+
import packageJSON from '../../package.json' with { type: 'json' }
7+
8+
async function listTables<TSchema extends Record<string, unknown>>(db: PostgresJsDatabase<TSchema>) {
9+
const res = await db.execute(sql`
10+
SELECT
11+
table_name
12+
FROM information_schema.tables
13+
WHERE table_schema = 'public';
14+
`)
15+
16+
return res.rows
17+
}
18+
19+
export async function migrate<TSchema extends Record<string, unknown>>(db: PostgresJsDatabase<TSchema>, bundledMigrations: {
20+
idx: number
21+
when: number
22+
tag: string
23+
hash: string
24+
sql: string[]
25+
}[]) {
26+
const log = useLogg(packageJSON.name).withFormat(Format.Pretty)
27+
const TABLE_NAME = sql.identifier('__drizzle_migrations')
28+
29+
await db.execute(
30+
sql`CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
31+
id bigserial PRIMARY KEY NOT NULL,
32+
hash text NOT NULL,
33+
tag text NOT NULL,
34+
created_at bigint NOT NULL
35+
);`,
36+
)
37+
38+
const deployments = await db.execute<{
39+
id: number
40+
hash: string
41+
created_at: number
42+
}>(
43+
sql`SELECT
44+
id,
45+
hash,
46+
created_at
47+
FROM ${TABLE_NAME}
48+
ORDER BY created_at DESC
49+
LIMIT 1;`,
50+
)
51+
52+
const deployment = deployments.rows.at(0)
53+
const migrations = bundledMigrations.filter((migration) => {
54+
const timestamp = deployment?.created_at ?? 0
55+
return !deployment || Number(timestamp) < migration.when
56+
})
57+
if (migrations.length === 0) {
58+
log.withField('tables', await listTables(db)).debug('no pending migrations')
59+
log.log('no pending migrations to apply')
60+
return
61+
}
62+
63+
await db.transaction(async (tx) => {
64+
for (let i = 0; i < migrations.length; i++) {
65+
const migration = migrations[i]
66+
67+
log.log(`${i + 1}. Deploying migration:`)
68+
log.log(` tag => ${migration.tag}`)
69+
log.log(` hash => ${migration.hash}`)
70+
for (const stmt of migration.sql) {
71+
await tx.execute(stmt)
72+
}
73+
74+
await tx.execute(sql`
75+
INSERT INTO ${TABLE_NAME} ("hash", "created_at", "tag") VALUES (
76+
${sql.raw(`'${migration.hash}'`)},
77+
${sql.raw(`${migration.when}`)},
78+
${sql.raw(`'${migration.tag}'`)}
79+
);
80+
`)
81+
}
82+
})
83+
84+
log.withField('tables', await listTables(db)).debug('migration successful')
85+
log.log(`all ${migrations.length} pending migrations applied!`)
86+
}

packages/drizzle-orm-browser-migrator/tsdown.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export default defineConfig({
44
entry: {
55
'index': './src/index.ts',
66
'pglite/index': './src/pglite/index.ts',
7+
'pg/index': './src/pg/index.ts',
78
},
89
unused: true,
910
fixedExtension: true,

0 commit comments

Comments
 (0)