feat: conditionally use transactions
This commit is contained in:
61
.vscode/launch.json
vendored
61
.vscode/launch.json
vendored
@@ -33,54 +33,39 @@
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Migrate CLI - create",
|
||||
"runtimeArgs": [
|
||||
"-r",
|
||||
"ts-node/register"
|
||||
],
|
||||
"args": [
|
||||
"src/bin/migrate.ts",
|
||||
"migrate:create",
|
||||
"second"
|
||||
],
|
||||
"env": {
|
||||
"PAYLOAD_CONFIG_PATH": "test/migrations-cli/config.ts"
|
||||
},
|
||||
"outputCapture": "std",
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"type": "node-terminal",
|
||||
"command": "ts-node src/bin/migrate.ts migrate",
|
||||
"request": "launch",
|
||||
"name": "Migrate CLI - migrate",
|
||||
"runtimeArgs": [
|
||||
"-r",
|
||||
"ts-node/register"
|
||||
],
|
||||
"args": [
|
||||
"src/bin/migrate.ts",
|
||||
"migrate",
|
||||
],
|
||||
"env": {
|
||||
"PAYLOAD_CONFIG_PATH": "test/migrations-cli/config.ts"
|
||||
"PAYLOAD_CONFIG_PATH": "test/migrations-cli/config.ts",
|
||||
"PAYLOAD_DATABASE": "postgres",
|
||||
"PAYLOAD_DROP_DATABASE": "true",
|
||||
},
|
||||
"outputCapture": "std",
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"type": "node-terminal",
|
||||
"command": "ts-node src/bin/migrate.ts migrate:status",
|
||||
"request": "launch",
|
||||
"name": "Migrate CLI - status",
|
||||
"runtimeArgs": [
|
||||
"-r",
|
||||
"ts-node/register"
|
||||
],
|
||||
"args": [
|
||||
"src/bin/migrate.ts",
|
||||
"migrate:status",
|
||||
],
|
||||
"env": {
|
||||
"PAYLOAD_CONFIG_PATH": "test/migrations-cli/config.ts"
|
||||
"PAYLOAD_CONFIG_PATH": "test/migrations-cli/config.ts",
|
||||
"PAYLOAD_DATABASE": "postgres",
|
||||
"PAYLOAD_DROP_DATABASE": "true",
|
||||
},
|
||||
"outputCapture": "std",
|
||||
},
|
||||
{
|
||||
"type": "node-terminal",
|
||||
"command": "ts-node src/bin/migrate.ts migrate:create yass",
|
||||
"request": "launch",
|
||||
"name": "Migrate CLI - create",
|
||||
"env": {
|
||||
// "PAYLOAD_CONFIG_PATH": "test/migrations-cli/config.ts",
|
||||
"PAYLOAD_CONFIG_PATH": "test/postgres/config.ts",
|
||||
"PAYLOAD_DATABASE": "postgres",
|
||||
// "PAYLOAD_DROP_DATABASE": "true",
|
||||
},
|
||||
"outputCapture": "std",
|
||||
},
|
||||
|
||||
@@ -12,11 +12,11 @@ import prompts from 'prompts';
|
||||
import { buildTable } from './schema/build';
|
||||
import type { GenericEnum, GenericRelation, GenericTable, PostgresAdapter } from './types';
|
||||
|
||||
const migrationTemplate = `
|
||||
const migrationTemplate = (upSQL?: string) => `
|
||||
import payload, { Payload } from 'payload';
|
||||
|
||||
export async function up(payload: Payload): Promise<void> {
|
||||
await payload.db.db.execute(\`{{SQL}}\`);
|
||||
${upSQL ? `await payload.db.db.execute(\`${upSQL}\`);` : '// Migration code'}
|
||||
};
|
||||
|
||||
export async function down(payload: Payload): Promise<void> {
|
||||
@@ -50,7 +50,7 @@ export const createMigration: CreateMigration = async function createMigration(
|
||||
const drizzleJsonBefore = generateDrizzleJson(JSON.parse(snapshotJSON));
|
||||
const drizzleJsonAfter = generateDrizzleJson(this.schema, drizzleJsonBefore.id);
|
||||
const sqlStatements = await generateMigration(drizzleJsonBefore, drizzleJsonAfter);
|
||||
fs.writeFileSync(filePath, migrationTemplate.replace('{{SQL}}', sqlStatements.join('\n')));
|
||||
fs.writeFileSync(filePath, migrationTemplate(sqlStatements.length ? sqlStatements?.join('\n') : undefined));
|
||||
|
||||
// TODO:
|
||||
// Get the most recent migration schema from the file system
|
||||
|
||||
@@ -7,9 +7,13 @@ import { migrateStatus } from './migrations/migrateStatus';
|
||||
import { migrateDown } from './migrations/migrateDown';
|
||||
import { migrateRefresh } from './migrations/migrateRefresh';
|
||||
import { migrateReset } from './migrations/migrateReset';
|
||||
import { DatabaseAdapter } from './types';
|
||||
import { BeginTransaction, CommitTransaction, DatabaseAdapter, RollbackTransaction } from './types';
|
||||
import { createMigration } from './migrations/createMigration';
|
||||
|
||||
const beginTransaction: BeginTransaction = async () => null;
|
||||
const rollbackTransaction: RollbackTransaction = async () => null;
|
||||
const commitTransaction: CommitTransaction = async () => null;
|
||||
|
||||
export function createDatabaseAdapter<T extends DatabaseAdapter>(args: MarkOptional<T,
|
||||
| 'transaction'
|
||||
| 'migrate'
|
||||
@@ -19,7 +23,8 @@ export function createDatabaseAdapter<T extends DatabaseAdapter>(args: MarkOptio
|
||||
| 'migrateRefresh'
|
||||
| 'migrateReset'
|
||||
| 'migrateFresh'
|
||||
| 'migrationDir'>): T {
|
||||
| 'migrationDir'
|
||||
>): T {
|
||||
// Need to implement DB Webpack config extensions here
|
||||
if (args.webpack) {
|
||||
const existingWebpackConfig = args.payload.config.admin.webpack ? args.payload.config.admin.webpack : (webpackConfig) => webpackConfig;
|
||||
@@ -39,6 +44,12 @@ export function createDatabaseAdapter<T extends DatabaseAdapter>(args: MarkOptio
|
||||
migrateRefresh,
|
||||
migrateReset,
|
||||
migrateFresh: async () => null,
|
||||
|
||||
// Default 'null' transaction functions
|
||||
beginTransaction,
|
||||
commitTransaction,
|
||||
rollbackTransaction,
|
||||
|
||||
...args,
|
||||
} as T;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export async function getMigrations({
|
||||
const existingMigrations = migrationQuery.docs as unknown as MigrationData[];
|
||||
|
||||
// Get the highest batch number from existing migrations
|
||||
const latestBatch = existingMigrations?.[0]?.batch || 0;
|
||||
const latestBatch = Number(existingMigrations?.[0]?.batch) || 0;
|
||||
|
||||
return {
|
||||
existingMigrations,
|
||||
|
||||
@@ -21,10 +21,11 @@ export async function migrate(this: DatabaseAdapter): Promise<void> {
|
||||
}
|
||||
|
||||
const start = Date.now();
|
||||
let transactionID;
|
||||
let transactionID: string | number | undefined;
|
||||
|
||||
payload.logger.info({ msg: `Migrating: ${migration.name}` });
|
||||
|
||||
try {
|
||||
payload.logger.info({ msg: `Migrating: ${migration.name}` });
|
||||
transactionID = await this.beginTransaction();
|
||||
await migration.up({ payload });
|
||||
payload.logger.info({ msg: `Migrated: ${migration.name} (${Date.now() - start}ms)` });
|
||||
@@ -34,9 +35,7 @@ export async function migrate(this: DatabaseAdapter): Promise<void> {
|
||||
name: migration.name,
|
||||
batch: newBatch,
|
||||
},
|
||||
req: {
|
||||
transactionID,
|
||||
} as PayloadRequest,
|
||||
...(transactionID && { req: { transactionID } as PayloadRequest }),
|
||||
});
|
||||
await this.commitTransaction(transactionID);
|
||||
} catch (err: unknown) {
|
||||
|
||||
@@ -16,6 +16,7 @@ export const readMigrationFiles = async ({
|
||||
const files = fs
|
||||
.readdirSync(payload.db.migrationDir)
|
||||
.sort()
|
||||
.filter((f) => f.endsWith('.ts'))
|
||||
.map((file) => {
|
||||
return path.resolve(payload.db.migrationDir, file);
|
||||
});
|
||||
|
||||
@@ -1,52 +1,3 @@
|
||||
/* eslint-disable no-console */
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults';
|
||||
|
||||
import path from 'path';
|
||||
import { buildConfig } from '../buildConfig';
|
||||
import { CollectionConfig } from '../../types';
|
||||
import { mongooseAdapter } from '../../src/mongoose';
|
||||
import payload from '../../src';
|
||||
|
||||
const Users: CollectionConfig = {
|
||||
slug: 'users',
|
||||
auth: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'custom',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'checkbox',
|
||||
type: 'checkbox',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// // @ts-expect-error partial
|
||||
// const mockAdapter: DatabaseAdapter = {
|
||||
// // payload: undefined,
|
||||
// migrationDir: path.resolve(__dirname, '.migrations'),
|
||||
// migrateStatus: async () => console.log('TODO: migrateStatus not implemented.'),
|
||||
// createMigration: async (): Promise<void> =>
|
||||
// console.log('TODO: createMigration not implemented.'),
|
||||
// migrate: async (): Promise<void> => console.log('TODO: migrate not implemented.'),
|
||||
// migrateDown: async (): Promise<void> =>
|
||||
// console.log('TODO: migrateDown not implemented.'),
|
||||
// migrateRefresh: async (): Promise<void> =>
|
||||
// console.log('TODO: migrateRefresh not implemented.'),
|
||||
// migrateReset: async (): Promise<void> =>
|
||||
// console.log('TODO: migrateReset not implemented.'),
|
||||
// migrateFresh: async (): Promise<void> =>
|
||||
// console.log('TODO: migrateFresh not implemented.'),
|
||||
// };
|
||||
|
||||
export default buildConfig({
|
||||
serverURL: 'http://localhost:3000',
|
||||
admin: {
|
||||
user: Users.slug,
|
||||
},
|
||||
collections: [Users],
|
||||
typescript: {
|
||||
outputFile: path.resolve(__dirname, 'payload-types.ts'),
|
||||
},
|
||||
db: mongooseAdapter({ payload, url: 'mongodb://127.0.0.1:27017/migrations-cli-test' }),
|
||||
});
|
||||
export default buildConfigWithDefaults({});
|
||||
|
||||
Reference in New Issue
Block a user