Skip to content

Commit

Permalink
feat(db-postgres): improve transaction support by passing req to migr…
Browse files Browse the repository at this point in the history
…ations
  • Loading branch information
DanRibbens committed Jan 8, 2024
1 parent 682eca2 commit 555d027
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 44 deletions.
13 changes: 11 additions & 2 deletions packages/db-postgres/src/migrate.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
/* eslint-disable no-restricted-syntax, no-await-in-loop */
import type { Payload } from 'payload'
import type { Migration } from 'payload/database'
import type { PayloadRequest } from 'payload/dist/express/types'

import { readMigrationFiles } from 'payload/database'
import { commitTransaction } from 'payload/dist/utilities/commitTransaction'
import { initTransaction } from 'payload/dist/utilities/initTransaction'
import { killTransaction } from 'payload/dist/utilities/killTransaction'
import prompts from 'prompts'

import type { PostgresAdapter } from './types'
Expand Down Expand Up @@ -42,11 +46,11 @@ export async function migrate(this: PostgresAdapter): Promise<void> {
const { confirm: runMigrations } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message:
"It looks like you've run Payload in dev mode, meaning you've dynamically pushed changes to your database.\n\n" +
"If you'd like to run migrations, data loss will occur. Would you like to proceed?",
type: 'confirm',
},
{
onCancel: () => {
Expand Down Expand Up @@ -79,14 +83,16 @@ async function runMigrationFile(payload: Payload, migration: Migration, batch: n
const { generateDrizzleJson } = require('drizzle-kit/utils')

const start = Date.now()
const req = {} as PayloadRequest

payload.logger.info({ msg: `Migrating: ${migration.name}` })

const pgAdapter = payload.db
const drizzleJSON = generateDrizzleJson(pgAdapter.schema)

try {
await migration.up({ payload })
await initTransaction(req)
await migration.up({ payload, req })
payload.logger.info({ msg: `Migrated: ${migration.name} (${Date.now() - start}ms)` })
await payload.create({
collection: 'payload-migrations',
Expand All @@ -95,8 +101,11 @@ async function runMigrationFile(payload: Payload, migration: Migration, batch: n
batch,
schema: drizzleJSON,
},
req,
})
await commitTransaction(req)
} catch (err: unknown) {
await killTransaction(req)
payload.logger.error({
err,
msg: parseError(err, `Error running migration ${migration.name}`),
Expand Down
17 changes: 9 additions & 8 deletions packages/db-postgres/src/migrateDown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import type { PayloadRequest } from 'payload/types'

import { getMigrations, readMigrationFiles } from 'payload/database'
import { commitTransaction } from 'payload/dist/utilities/commitTransaction'
import { initTransaction } from 'payload/dist/utilities/initTransaction'
import { killTransaction } from 'payload/dist/utilities/killTransaction'

import type { PostgresAdapter } from './types'

Expand Down Expand Up @@ -32,12 +35,12 @@ export async function migrateDown(this: PostgresAdapter): Promise<void> {
}

const start = Date.now()
let transactionID
const req = {} as PayloadRequest

try {
payload.logger.info({ msg: `Migrating down: ${migrationFile.name}` })
transactionID = await this.beginTransaction()
await migrationFile.down({ payload })
await initTransaction(req)
await migrationFile.down({ payload, req })
payload.logger.info({
msg: `Migrated down: ${migrationFile.name} (${Date.now() - start}ms)`,
})
Expand All @@ -47,15 +50,13 @@ export async function migrateDown(this: PostgresAdapter): Promise<void> {
await payload.delete({
id: migration.id,
collection: 'payload-migrations',
req: {
transactionID,
} as PayloadRequest,
req,
})
}

await this.commitTransaction(transactionID)
await commitTransaction(req)
} catch (err: unknown) {
await this.rollbackTransaction(transactionID)
await killTransaction(req)

payload.logger.error({
err,
Expand Down
22 changes: 12 additions & 10 deletions packages/db-postgres/src/migrateFresh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import type { PayloadRequest } from 'payload/types'

import { sql } from 'drizzle-orm'
import { readMigrationFiles } from 'payload/database'
import { commitTransaction } from 'payload/dist/utilities/commitTransaction'
import { initTransaction } from 'payload/dist/utilities/initTransaction'
import { killTransaction } from 'payload/dist/utilities/killTransaction'
import prompts from 'prompts'

import type { PostgresAdapter } from './types'
Expand All @@ -17,9 +20,9 @@ export async function migrateFresh(this: PostgresAdapter): Promise<void> {
const { confirm: acceptWarning } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message: `WARNING: This will drop your database and run all migrations. Are you sure you want to proceed?`,
type: 'confirm',
},
{
onCancel: () => {
Expand All @@ -36,36 +39,35 @@ export async function migrateFresh(this: PostgresAdapter): Promise<void> {
msg: `Dropping database.`,
})

await this.drizzle.execute(sql`drop schema public cascade;\ncreate schema public;`)
await this.drizzle.execute(sql`drop schema public cascade;
create schema public;`)

const migrationFiles = await readMigrationFiles({ payload })
payload.logger.debug({
msg: `Found ${migrationFiles.length} migration files.`,
})

let transactionID
const req = {} as PayloadRequest
// Run all migrate up
for (const migration of migrationFiles) {
payload.logger.info({ msg: `Migrating: ${migration.name}` })
try {
const start = Date.now()
transactionID = await this.beginTransaction()
await migration.up({ payload })
await initTransaction(req)
await migration.up({ payload, req })
await payload.create({
collection: 'payload-migrations',
data: {
name: migration.name,
batch: 1,
},
req: {
transactionID,
} as PayloadRequest,
req,
})
await this.commitTransaction(transactionID)
await commitTransaction(req)

payload.logger.info({ msg: `Migrated: ${migration.name} (${Date.now() - start}ms)` })
} catch (err: unknown) {
await this.rollbackTransaction(transactionID)
await killTransaction(req)
payload.logger.error({
err,
msg: parseError(err, `Error running migration ${migration.name}. Rolling back`),
Expand Down
29 changes: 14 additions & 15 deletions packages/db-postgres/src/migrateRefresh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import type { PayloadRequest } from 'payload/types'

import { getMigrations, readMigrationFiles } from 'payload/database'
import { DatabaseError } from 'pg'
import { commitTransaction } from 'payload/dist/utilities/commitTransaction'
import { initTransaction } from 'payload/dist/utilities/initTransaction'
import { killTransaction } from 'payload/dist/utilities/killTransaction'

import type { PostgresAdapter } from './types'

Expand All @@ -29,7 +31,7 @@ export async function migrateRefresh(this: PostgresAdapter) {
msg: `Rolling back batch ${latestBatch} consisting of ${existingMigrations.length} migration(s).`,
})

let transactionID
const req = {} as PayloadRequest

// Reverse order of migrations to rollback
existingMigrations.reverse()
Expand All @@ -43,8 +45,8 @@ export async function migrateRefresh(this: PostgresAdapter) {

payload.logger.info({ msg: `Migrating down: ${migration.name}` })
const start = Date.now()
transactionID = await this.beginTransaction()
await migrationFile.down({ payload })
await initTransaction(req)
await migrationFile.down({ payload, req })
payload.logger.info({
msg: `Migrated down: ${migration.name} (${Date.now() - start}ms)`,
})
Expand All @@ -53,18 +55,17 @@ export async function migrateRefresh(this: PostgresAdapter) {
if (tableExists) {
await payload.delete({
collection: 'payload-migrations',
req: {
transactionID,
} as PayloadRequest,
req,
where: {
name: {
equals: migration.name,
},
},
})
}
await commitTransaction(req)
} catch (err: unknown) {
await this.rollbackTransaction(transactionID)
await killTransaction(req)
payload.logger.error({
err,
msg: parseError(err, `Error running migration ${migration.name}. Rolling back.`),
Expand All @@ -78,23 +79,21 @@ export async function migrateRefresh(this: PostgresAdapter) {
payload.logger.info({ msg: `Migrating: ${migration.name}` })
try {
const start = Date.now()
transactionID = await this.beginTransaction()
await migration.up({ payload })
await initTransaction(req)
await migration.up({ payload, req })
await payload.create({
collection: 'payload-migrations',
data: {
name: migration.name,
executed: true,
},
req: {
transactionID,
} as PayloadRequest,
req,
})
await this.commitTransaction(transactionID)
await commitTransaction(req)

payload.logger.info({ msg: `Migrated: ${migration.name} (${Date.now() - start}ms)` })
} catch (err: unknown) {
await this.rollbackTransaction(transactionID)
await killTransaction(req)
payload.logger.error({
err,
msg: parseError(err, `Error running migration ${migration.name}. Rolling back.`),
Expand Down
19 changes: 10 additions & 9 deletions packages/db-postgres/src/migrateReset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import type { PayloadRequest } from 'payload/types'

import { getMigrations, readMigrationFiles } from 'payload/database'
import { commitTransaction } from 'payload/dist/utilities/commitTransaction'
import { initTransaction } from 'payload/dist/utilities/initTransaction'
import { killTransaction } from 'payload/dist/utilities/killTransaction'

import type { PostgresAdapter } from './types'

Expand All @@ -21,10 +24,10 @@ export async function migrateReset(this: PostgresAdapter): Promise<void> {
return
}

const req = {} as PayloadRequest

// Rollback all migrations in order
for (const migration of existingMigrations) {
let transactionID

const migrationFile = migrationFiles.find((m) => m.name === migration.name)
try {
if (!migrationFile) {
Expand All @@ -33,8 +36,8 @@ export async function migrateReset(this: PostgresAdapter): Promise<void> {

const start = Date.now()
payload.logger.info({ msg: `Migrating down: ${migrationFile.name}` })
transactionID = await this.beginTransaction()
await migrationFile.down({ payload })
await initTransaction(req)
await migrationFile.down({ payload, req })
payload.logger.info({
msg: `Migrated down: ${migrationFile.name} (${Date.now() - start}ms)`,
})
Expand All @@ -44,19 +47,17 @@ export async function migrateReset(this: PostgresAdapter): Promise<void> {
await payload.delete({
id: migration.id,
collection: 'payload-migrations',
req: {
transactionID,
} as PayloadRequest,
req,
})
}

await this.commitTransaction(transactionID)
await commitTransaction(req)
} catch (err: unknown) {
let msg = `Error running migration ${migrationFile.name}.`

if (err instanceof Error) msg += ` ${err.message}`

await this.rollbackTransaction(transactionID)
await killTransaction(req)
payload.logger.error({
err,
msg,
Expand Down

0 comments on commit 555d027

Please sign in to comment.