chore: fix up fresh, refresh, and reset migration operations
This commit is contained in:
1
packages/db-mongodb/.gitignore
vendored
Normal file
1
packages/db-mongodb/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/migrations
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
"mongoose": "6.11.4",
|
"mongoose": "6.11.4",
|
||||||
"mongoose-aggregate-paginate-v2": "1.0.6",
|
"mongoose-aggregate-paginate-v2": "1.0.6",
|
||||||
"mongoose-paginate-v2": "1.7.22",
|
"mongoose-paginate-v2": "1.7.22",
|
||||||
|
"prompts": "2.4.2",
|
||||||
"uuid": "9.0.0"
|
"uuid": "9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { Payload } from 'payload'
|
|||||||
import type { BaseDatabaseAdapter } from 'payload/database'
|
import type { BaseDatabaseAdapter } from 'payload/database'
|
||||||
|
|
||||||
import mongoose from 'mongoose'
|
import mongoose from 'mongoose'
|
||||||
|
import path from 'path'
|
||||||
import { createDatabaseAdapter } from 'payload/database'
|
import { createDatabaseAdapter } from 'payload/database'
|
||||||
import { createMigration } from 'payload/database'
|
import { createMigration } from 'payload/database'
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ import { findGlobalVersions } from './findGlobalVersions'
|
|||||||
import { findOne } from './findOne'
|
import { findOne } from './findOne'
|
||||||
import { findVersions } from './findVersions'
|
import { findVersions } from './findVersions'
|
||||||
import { init } from './init'
|
import { init } from './init'
|
||||||
|
import { migrateFresh } from './migrateFresh'
|
||||||
import { queryDrafts } from './queryDrafts'
|
import { queryDrafts } from './queryDrafts'
|
||||||
import { beginTransaction } from './transactions/beginTransaction'
|
import { beginTransaction } from './transactions/beginTransaction'
|
||||||
import { commitTransaction } from './transactions/commitTransaction'
|
import { commitTransaction } from './transactions/commitTransaction'
|
||||||
@@ -83,23 +85,34 @@ declare module 'payload' {
|
|||||||
export function mongooseAdapter({
|
export function mongooseAdapter({
|
||||||
autoPluralization = true,
|
autoPluralization = true,
|
||||||
connectOptions,
|
connectOptions,
|
||||||
migrationDir,
|
migrationDir: migrationDirArg,
|
||||||
url,
|
url,
|
||||||
}: Args): MongooseAdapterResult {
|
}: Args): MongooseAdapterResult {
|
||||||
function adapter({ payload }: { payload: Payload }) {
|
function adapter({ payload }: { payload: Payload }) {
|
||||||
|
const migrationDir = migrationDirArg || path.resolve(process.cwd(), 'src/migrations')
|
||||||
mongoose.set('strictQuery', false)
|
mongoose.set('strictQuery', false)
|
||||||
|
|
||||||
extendWebpackConfig(payload.config)
|
extendWebpackConfig(payload.config)
|
||||||
extendViteConfig(payload.config)
|
extendViteConfig(payload.config)
|
||||||
|
|
||||||
return createDatabaseAdapter<MongooseAdapter>({
|
return createDatabaseAdapter<MongooseAdapter>({
|
||||||
|
name: 'mongoose',
|
||||||
|
|
||||||
|
// Mongoose-specific
|
||||||
autoPluralization,
|
autoPluralization,
|
||||||
beginTransaction,
|
|
||||||
collections: {},
|
collections: {},
|
||||||
commitTransaction,
|
|
||||||
connect,
|
|
||||||
connectOptions: connectOptions || {},
|
connectOptions: connectOptions || {},
|
||||||
connection: undefined,
|
connection: undefined,
|
||||||
|
globals: undefined,
|
||||||
|
mongoMemoryServer: undefined,
|
||||||
|
sessions: {},
|
||||||
|
url,
|
||||||
|
versions: {},
|
||||||
|
|
||||||
|
// DatabaseAdapter
|
||||||
|
beginTransaction,
|
||||||
|
commitTransaction,
|
||||||
|
connect,
|
||||||
create,
|
create,
|
||||||
createGlobal,
|
createGlobal,
|
||||||
createGlobalVersion,
|
createGlobalVersion,
|
||||||
@@ -115,21 +128,16 @@ export function mongooseAdapter({
|
|||||||
findGlobalVersions,
|
findGlobalVersions,
|
||||||
findOne,
|
findOne,
|
||||||
findVersions,
|
findVersions,
|
||||||
globals: undefined,
|
|
||||||
init,
|
init,
|
||||||
...(migrationDir && { migrationDir }),
|
migrateFresh,
|
||||||
name: 'mongoose',
|
migrationDir,
|
||||||
mongoMemoryServer: undefined,
|
|
||||||
payload,
|
payload,
|
||||||
queryDrafts,
|
queryDrafts,
|
||||||
rollbackTransaction,
|
rollbackTransaction,
|
||||||
sessions: {},
|
|
||||||
updateGlobal,
|
updateGlobal,
|
||||||
updateGlobalVersion,
|
updateGlobalVersion,
|
||||||
updateOne,
|
updateOne,
|
||||||
updateVersion,
|
updateVersion,
|
||||||
url,
|
|
||||||
versions: {},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
73
packages/db-mongodb/src/migrateFresh.ts
Normal file
73
packages/db-mongodb/src/migrateFresh.ts
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import type { PayloadRequest } from 'payload/types'
|
||||||
|
|
||||||
|
import { readMigrationFiles } from 'payload/database'
|
||||||
|
import prompts from 'prompts'
|
||||||
|
|
||||||
|
import type { MongooseAdapter } from '.'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop the current database and run all migrate up functions
|
||||||
|
*/
|
||||||
|
export async function migrateFresh(this: MongooseAdapter): Promise<void> {
|
||||||
|
const { payload } = this
|
||||||
|
|
||||||
|
const { confirm: acceptWarning } = await prompts(
|
||||||
|
{
|
||||||
|
name: 'confirm',
|
||||||
|
initial: false,
|
||||||
|
message: `WARNING: This will drop your database and run all migrations. Are you sure you want to proceed?`,
|
||||||
|
type: 'confirm',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onCancel: () => {
|
||||||
|
process.exit(0)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!acceptWarning) {
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Dropping database.`,
|
||||||
|
})
|
||||||
|
|
||||||
|
await this.connection.dropDatabase()
|
||||||
|
|
||||||
|
const migrationFiles = await readMigrationFiles({ payload })
|
||||||
|
payload.logger.debug({
|
||||||
|
msg: `Found ${migrationFiles.length} migration files.`,
|
||||||
|
})
|
||||||
|
|
||||||
|
let transactionID
|
||||||
|
// 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 payload.create({
|
||||||
|
collection: 'payload-migrations',
|
||||||
|
data: {
|
||||||
|
name: migration.name,
|
||||||
|
batch: 1,
|
||||||
|
},
|
||||||
|
req: {
|
||||||
|
transactionID,
|
||||||
|
} as PayloadRequest,
|
||||||
|
})
|
||||||
|
await this.commitTransaction(transactionID)
|
||||||
|
|
||||||
|
payload.logger.info({ msg: `Migrated: ${migration.name} (${Date.now() - start}ms)` })
|
||||||
|
} catch (err: unknown) {
|
||||||
|
await this.rollbackTransaction(transactionID)
|
||||||
|
payload.logger.error({
|
||||||
|
err,
|
||||||
|
msg: `Error running migration ${migration.name}. Rolling back.`,
|
||||||
|
})
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,10 @@ import { findOne } from './findOne'
|
|||||||
import { findVersions } from './findVersions'
|
import { findVersions } from './findVersions'
|
||||||
import { init } from './init'
|
import { init } from './init'
|
||||||
import { migrate } from './migrate'
|
import { migrate } from './migrate'
|
||||||
|
import { migrateDown } from './migrateDown'
|
||||||
|
import { migrateFresh } from './migrateFresh'
|
||||||
|
import { migrateRefresh } from './migrateRefresh'
|
||||||
|
import { migrateReset } from './migrateReset'
|
||||||
import { migrateStatus } from './migrateStatus'
|
import { migrateStatus } from './migrateStatus'
|
||||||
import { queryDrafts } from './queryDrafts'
|
import { queryDrafts } from './queryDrafts'
|
||||||
import { beginTransaction } from './transactions/beginTransaction'
|
import { beginTransaction } from './transactions/beginTransaction'
|
||||||
@@ -77,6 +81,10 @@ export function postgresAdapter(args: Args): PostgresAdapterResult {
|
|||||||
findVersions,
|
findVersions,
|
||||||
init,
|
init,
|
||||||
migrate,
|
migrate,
|
||||||
|
migrateDown,
|
||||||
|
migrateFresh,
|
||||||
|
migrateRefresh,
|
||||||
|
migrateReset,
|
||||||
migrateStatus,
|
migrateStatus,
|
||||||
migrationDir,
|
migrationDir,
|
||||||
payload,
|
payload,
|
||||||
|
|||||||
69
packages/db-postgres/src/migrateDown.ts
Normal file
69
packages/db-postgres/src/migrateDown.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/* eslint-disable no-restricted-syntax, no-await-in-loop */
|
||||||
|
import type { PayloadRequest } from 'payload/types'
|
||||||
|
|
||||||
|
import { getMigrations, readMigrationFiles } from 'payload/database'
|
||||||
|
|
||||||
|
import type { PostgresAdapter } from './types'
|
||||||
|
|
||||||
|
import { migrationTableExists } from './utilities/migrationTableExists'
|
||||||
|
|
||||||
|
export async function migrateDown(this: PostgresAdapter): Promise<void> {
|
||||||
|
const { payload } = this
|
||||||
|
const migrationFiles = await readMigrationFiles({ payload })
|
||||||
|
|
||||||
|
const { existingMigrations, latestBatch } = await getMigrations({
|
||||||
|
payload,
|
||||||
|
})
|
||||||
|
|
||||||
|
const migrationsToRollback = existingMigrations.filter(
|
||||||
|
(migration) => migration.batch === latestBatch && migration.batch !== -1,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!migrationsToRollback?.length) {
|
||||||
|
payload.logger.info({ msg: 'No migrations to rollback.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Rolling back batch ${latestBatch} consisting of ${migrationsToRollback.length} migration(s).`,
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const migration of migrationsToRollback) {
|
||||||
|
const migrationFile = migrationFiles.find((m) => m.name === migration.name)
|
||||||
|
if (!migrationFile) {
|
||||||
|
throw new Error(`Migration ${migration.name} not found locally.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = Date.now()
|
||||||
|
let transactionID
|
||||||
|
|
||||||
|
try {
|
||||||
|
payload.logger.info({ msg: `Migrating down: ${migrationFile.name}` })
|
||||||
|
transactionID = await this.beginTransaction()
|
||||||
|
await migrationFile.down({ payload })
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Migrated down: ${migrationFile.name} (${Date.now() - start}ms)`,
|
||||||
|
})
|
||||||
|
|
||||||
|
const tableExists = await migrationTableExists(this.drizzle)
|
||||||
|
if (tableExists) {
|
||||||
|
await payload.delete({
|
||||||
|
id: migration.id,
|
||||||
|
collection: 'payload-migrations',
|
||||||
|
req: {
|
||||||
|
transactionID,
|
||||||
|
} as PayloadRequest,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.commitTransaction(transactionID)
|
||||||
|
} catch (err: unknown) {
|
||||||
|
await this.rollbackTransaction(transactionID)
|
||||||
|
payload.logger.error({
|
||||||
|
err,
|
||||||
|
msg: `Error running migration ${migrationFile.name}`,
|
||||||
|
})
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
74
packages/db-postgres/src/migrateFresh.ts
Normal file
74
packages/db-postgres/src/migrateFresh.ts
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import type { PayloadRequest } from 'payload/types'
|
||||||
|
|
||||||
|
import { sql } from 'drizzle-orm'
|
||||||
|
import { readMigrationFiles } from 'payload/database'
|
||||||
|
import prompts from 'prompts'
|
||||||
|
|
||||||
|
import type { PostgresAdapter } from './types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop the current database and run all migrate up functions
|
||||||
|
*/
|
||||||
|
export async function migrateFresh(this: PostgresAdapter): Promise<void> {
|
||||||
|
const { payload } = this
|
||||||
|
|
||||||
|
const { confirm: acceptWarning } = await prompts(
|
||||||
|
{
|
||||||
|
name: 'confirm',
|
||||||
|
initial: false,
|
||||||
|
message: `WARNING: This will drop your database and run all migrations. Are you sure you want to proceed?`,
|
||||||
|
type: 'confirm',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onCancel: () => {
|
||||||
|
process.exit(0)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!acceptWarning) {
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Dropping database.`,
|
||||||
|
})
|
||||||
|
|
||||||
|
await this.drizzle.execute(sql`drop schema public cascade;\ncreate schema public;`)
|
||||||
|
|
||||||
|
const migrationFiles = await readMigrationFiles({ payload })
|
||||||
|
payload.logger.debug({
|
||||||
|
msg: `Found ${migrationFiles.length} migration files.`,
|
||||||
|
})
|
||||||
|
|
||||||
|
let transactionID
|
||||||
|
// 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 payload.create({
|
||||||
|
collection: 'payload-migrations',
|
||||||
|
data: {
|
||||||
|
name: migration.name,
|
||||||
|
batch: 1,
|
||||||
|
},
|
||||||
|
req: {
|
||||||
|
transactionID,
|
||||||
|
} as PayloadRequest,
|
||||||
|
})
|
||||||
|
await this.commitTransaction(transactionID)
|
||||||
|
|
||||||
|
payload.logger.info({ msg: `Migrated: ${migration.name} (${Date.now() - start}ms)` })
|
||||||
|
} catch (err: unknown) {
|
||||||
|
await this.rollbackTransaction(transactionID)
|
||||||
|
payload.logger.error({
|
||||||
|
err,
|
||||||
|
msg: `Error running migration ${migration.name}. Rolling back.`,
|
||||||
|
})
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
111
packages/db-postgres/src/migrateRefresh.ts
Normal file
111
packages/db-postgres/src/migrateRefresh.ts
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/* eslint-disable no-restricted-syntax, no-await-in-loop */
|
||||||
|
import type { PayloadRequest } from 'payload/types'
|
||||||
|
|
||||||
|
import { getMigrations, readMigrationFiles } from 'payload/database'
|
||||||
|
|
||||||
|
import type { PostgresAdapter } from './types'
|
||||||
|
|
||||||
|
import { migrationTableExists } from './utilities/migrationTableExists'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run all migration down functions before running up
|
||||||
|
*/
|
||||||
|
export async function migrateRefresh(this: PostgresAdapter) {
|
||||||
|
const { payload } = this
|
||||||
|
const migrationFiles = await readMigrationFiles({ payload })
|
||||||
|
|
||||||
|
const { existingMigrations, latestBatch } = await getMigrations({
|
||||||
|
payload,
|
||||||
|
})
|
||||||
|
|
||||||
|
const migrationsToRollback = existingMigrations.filter(
|
||||||
|
(migration) => migration.batch === latestBatch && migration.batch !== -1,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!migrationsToRollback?.length) {
|
||||||
|
payload.logger.info({ msg: 'No migrations to rollback.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Rolling back batch ${latestBatch} consisting of ${migrationsToRollback.length} migration(s).`,
|
||||||
|
})
|
||||||
|
|
||||||
|
let transactionID
|
||||||
|
|
||||||
|
// Reverse order of migrations to rollback
|
||||||
|
migrationsToRollback.reverse()
|
||||||
|
|
||||||
|
for (const migration of migrationsToRollback) {
|
||||||
|
try {
|
||||||
|
const migrationFile = migrationFiles.find((m) => m.name === migration.name)
|
||||||
|
if (!migrationFile) {
|
||||||
|
throw new Error(`Migration ${migration.name} not found locally.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.logger.info({ msg: `Migrating down: ${migration.name}` })
|
||||||
|
const start = Date.now()
|
||||||
|
transactionID = await this.beginTransaction()
|
||||||
|
await migrationFile.down({ payload })
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Migrated down: ${migration.name} (${Date.now() - start}ms)`,
|
||||||
|
})
|
||||||
|
|
||||||
|
const tableExists = await migrationTableExists(this.drizzle)
|
||||||
|
if (tableExists) {
|
||||||
|
await payload.delete({
|
||||||
|
collection: 'payload-migrations',
|
||||||
|
req: {
|
||||||
|
transactionID,
|
||||||
|
} as PayloadRequest,
|
||||||
|
where: {
|
||||||
|
name: {
|
||||||
|
equals: migration.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (err: unknown) {
|
||||||
|
await this.rollbackTransaction(transactionID)
|
||||||
|
let msg = `Error running migration ${migration.name}. Rolling back.`
|
||||||
|
if (err instanceof Error) {
|
||||||
|
msg += ` ${err.message}`
|
||||||
|
}
|
||||||
|
payload.logger.error({
|
||||||
|
err,
|
||||||
|
msg,
|
||||||
|
})
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 payload.create({
|
||||||
|
collection: 'payload-migrations',
|
||||||
|
data: {
|
||||||
|
name: migration.name,
|
||||||
|
executed: true,
|
||||||
|
},
|
||||||
|
req: {
|
||||||
|
transactionID,
|
||||||
|
} as PayloadRequest,
|
||||||
|
})
|
||||||
|
await this.commitTransaction(transactionID)
|
||||||
|
|
||||||
|
payload.logger.info({ msg: `Migrated: ${migration.name} (${Date.now() - start}ms)` })
|
||||||
|
} catch (err: unknown) {
|
||||||
|
await this.rollbackTransaction(transactionID)
|
||||||
|
payload.logger.error({
|
||||||
|
err,
|
||||||
|
msg: `Error running migration ${migration.name}. Rolling back.`,
|
||||||
|
})
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
packages/db-postgres/src/migrateReset.ts
Normal file
81
packages/db-postgres/src/migrateReset.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/* eslint-disable no-restricted-syntax, no-await-in-loop */
|
||||||
|
import type { PayloadRequest } from 'payload/types'
|
||||||
|
|
||||||
|
import { getMigrations, readMigrationFiles } from 'payload/database'
|
||||||
|
|
||||||
|
import type { PostgresAdapter } from './types'
|
||||||
|
|
||||||
|
import { migrationTableExists } from './utilities/migrationTableExists'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run all migrate down functions
|
||||||
|
*/
|
||||||
|
export async function migrateReset(this: PostgresAdapter): Promise<void> {
|
||||||
|
const { payload } = this
|
||||||
|
const migrationFiles = await readMigrationFiles({ payload })
|
||||||
|
|
||||||
|
const { existingMigrations } = await getMigrations({ payload })
|
||||||
|
|
||||||
|
if (!existingMigrations?.length) {
|
||||||
|
payload.logger.info({ msg: 'No migrations to reset.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rollback all migrations in order
|
||||||
|
for (const migration of existingMigrations) {
|
||||||
|
const migrationFile = migrationFiles.find((m) => m.name === migration.name)
|
||||||
|
if (!migrationFile) {
|
||||||
|
throw new Error(`Migration ${migration.name} not found locally.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = Date.now()
|
||||||
|
let transactionID
|
||||||
|
|
||||||
|
try {
|
||||||
|
payload.logger.info({ msg: `Migrating down: ${migrationFile.name}` })
|
||||||
|
transactionID = await this.beginTransaction()
|
||||||
|
await migrationFile.down({ payload })
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Migrated down: ${migrationFile.name} (${Date.now() - start}ms)`,
|
||||||
|
})
|
||||||
|
|
||||||
|
const tableExists = await migrationTableExists(this.drizzle)
|
||||||
|
if (tableExists) {
|
||||||
|
await payload.delete({
|
||||||
|
id: migration.id,
|
||||||
|
collection: 'payload-migrations',
|
||||||
|
req: {
|
||||||
|
transactionID,
|
||||||
|
} as PayloadRequest,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.commitTransaction(transactionID)
|
||||||
|
} catch (err: unknown) {
|
||||||
|
await this.rollbackTransaction(transactionID)
|
||||||
|
payload.logger.error({
|
||||||
|
err,
|
||||||
|
msg: `Error running migration ${migrationFile.name}`,
|
||||||
|
})
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete dev migration
|
||||||
|
|
||||||
|
const tableExists = await migrationTableExists(this.drizzle)
|
||||||
|
if (tableExists) {
|
||||||
|
try {
|
||||||
|
await payload.delete({
|
||||||
|
collection: 'payload-migrations',
|
||||||
|
where: {
|
||||||
|
batch: {
|
||||||
|
equals: -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (err: unknown) {
|
||||||
|
payload.logger.error({ error: err, msg: 'Error deleting dev migration' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,22 +2,78 @@
|
|||||||
import type { PayloadRequest } from '../../express/types'
|
import type { PayloadRequest } from '../../express/types'
|
||||||
import type { BaseDatabaseAdapter } from '../types'
|
import type { BaseDatabaseAdapter } from '../types'
|
||||||
|
|
||||||
|
import { getMigrations } from './getMigrations'
|
||||||
import { readMigrationFiles } from './readMigrationFiles'
|
import { readMigrationFiles } from './readMigrationFiles'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset and re-run all migrations.
|
* Run all migration down functions before running up
|
||||||
*/
|
*/
|
||||||
export async function migrateRefresh(this: BaseDatabaseAdapter) {
|
export async function migrateRefresh(this: BaseDatabaseAdapter) {
|
||||||
const { payload } = this
|
const { payload } = this
|
||||||
const migrationFiles = await readMigrationFiles({ payload })
|
const migrationFiles = await readMigrationFiles({ payload })
|
||||||
|
|
||||||
// Clear all migrations
|
const { existingMigrations, latestBatch } = await getMigrations({
|
||||||
await payload.delete({
|
payload,
|
||||||
collection: 'payload-migrations',
|
|
||||||
where: {}, // All migrations
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const migrationsToRollback = existingMigrations.filter(
|
||||||
|
(migration) => migration.batch === latestBatch && migration.batch !== -1,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!migrationsToRollback?.length) {
|
||||||
|
payload.logger.info({ msg: 'No migrations to rollback.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Rolling back batch ${latestBatch} consisting of ${migrationsToRollback.length} migration(s).`,
|
||||||
|
})
|
||||||
|
|
||||||
let transactionID
|
let transactionID
|
||||||
// Run all migrations
|
|
||||||
|
// Reverse order of migrations to rollback
|
||||||
|
migrationsToRollback.reverse()
|
||||||
|
|
||||||
|
for (const migration of migrationsToRollback) {
|
||||||
|
try {
|
||||||
|
const migrationFile = migrationFiles.find((m) => m.name === migration.name)
|
||||||
|
if (!migrationFile) {
|
||||||
|
throw new Error(`Migration ${migration.name} not found locally.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.logger.info({ msg: `Migrating down: ${migration.name}` })
|
||||||
|
const start = Date.now()
|
||||||
|
transactionID = await this.beginTransaction()
|
||||||
|
await migrationFile.down({ payload })
|
||||||
|
payload.logger.info({
|
||||||
|
msg: `Migrated down: ${migration.name} (${Date.now() - start}ms)`,
|
||||||
|
})
|
||||||
|
await payload.delete({
|
||||||
|
collection: 'payload-migrations',
|
||||||
|
req: {
|
||||||
|
transactionID,
|
||||||
|
} as PayloadRequest,
|
||||||
|
where: {
|
||||||
|
name: {
|
||||||
|
equals: migration.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (err: unknown) {
|
||||||
|
await this.rollbackTransaction(transactionID)
|
||||||
|
let msg = `Error running migration ${migration.name}. Rolling back.`
|
||||||
|
if (err instanceof Error) {
|
||||||
|
msg += ` ${err.message}`
|
||||||
|
}
|
||||||
|
payload.logger.error({
|
||||||
|
err,
|
||||||
|
msg,
|
||||||
|
})
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run all migrate up
|
||||||
for (const migration of migrationFiles) {
|
for (const migration of migrationFiles) {
|
||||||
payload.logger.info({ msg: `Migrating: ${migration.name}` })
|
payload.logger.info({ msg: `Migrating: ${migration.name}` })
|
||||||
try {
|
try {
|
||||||
@@ -41,7 +97,7 @@ export async function migrateRefresh(this: BaseDatabaseAdapter) {
|
|||||||
await this.rollbackTransaction(transactionID)
|
await this.rollbackTransaction(transactionID)
|
||||||
payload.logger.error({
|
payload.logger.error({
|
||||||
err,
|
err,
|
||||||
msg: `Error running migration ${migration.name}`,
|
msg: `Error running migration ${migration.name}. Rolling back.`,
|
||||||
})
|
})
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export async function up({ payload }: MigrateUpArgs): Promise<void> {
|
|||||||
// Migration code
|
// Migration code
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function down({ payload }: MigrateUpArgs): Promise<void> {
|
export async function down({ payload }: MigrateDownArgs): Promise<void> {
|
||||||
// Migration code
|
// Migration code
|
||||||
};
|
};
|
||||||
`
|
`
|
||||||
|
|||||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -293,6 +293,9 @@ importers:
|
|||||||
mongoose-paginate-v2:
|
mongoose-paginate-v2:
|
||||||
specifier: 1.7.22
|
specifier: 1.7.22
|
||||||
version: 1.7.22
|
version: 1.7.22
|
||||||
|
prompts:
|
||||||
|
specifier: 2.4.2
|
||||||
|
version: 2.4.2
|
||||||
uuid:
|
uuid:
|
||||||
specifier: 9.0.0
|
specifier: 9.0.0
|
||||||
version: 9.0.0
|
version: 9.0.0
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const bundlerAdapters = {
|
|||||||
|
|
||||||
const databaseAdapters = {
|
const databaseAdapters = {
|
||||||
mongoose: mongooseAdapter({
|
mongoose: mongooseAdapter({
|
||||||
|
migrationDir: path.resolve(__dirname, '../packages/db-mongodb/migrations'),
|
||||||
url: 'mongodb://127.0.0.1/payloadtests',
|
url: 'mongodb://127.0.0.1/payloadtests',
|
||||||
}),
|
}),
|
||||||
postgres: postgresAdapter({
|
postgres: postgresAdapter({
|
||||||
|
|||||||
Reference in New Issue
Block a user