fix: rewrite the AddUserAvatarCacheFields migration for Overseerr merge
This commit is contained in:
@@ -77,7 +77,7 @@ const postgresDevConfig: DataSourceOptions = {
|
||||
database: process.env.DB_NAME ?? 'seerr',
|
||||
ssl: buildSslConfig(),
|
||||
synchronize: false,
|
||||
migrationsRun: true,
|
||||
migrationsRun: false,
|
||||
logging: boolFromEnv('DB_LOG_QUERIES'),
|
||||
entities: ['server/entity/**/*.ts'],
|
||||
migrations: ['server/migration/postgres/**/*.ts'],
|
||||
|
||||
@@ -60,10 +60,12 @@ if (!appDataPermissions()) {
|
||||
app
|
||||
.prepare()
|
||||
.then(async () => {
|
||||
const dbConnection = await dataSource.initialize();
|
||||
|
||||
// Run Overseerr to Seerr migration
|
||||
await checkOverseerrMerge(dbConnection);
|
||||
await checkOverseerrMerge();
|
||||
|
||||
const dbConnection = dataSource.isInitialized
|
||||
? dataSource
|
||||
: await dataSource.initialize();
|
||||
|
||||
// Run migrations in production
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
|
||||
@@ -1,19 +1,47 @@
|
||||
import { MediaServerType } from '@server/constants/server';
|
||||
import { getRepository } from '@server/datasource';
|
||||
import dataSource, { getRepository } from '@server/datasource';
|
||||
import Media from '@server/entity/Media';
|
||||
import Settings from '@server/lib/settings';
|
||||
import logger from '@server/logger';
|
||||
import type { DataSource } from 'typeorm';
|
||||
import type { MigrationInterface, MixedList, QueryRunner } from 'typeorm';
|
||||
|
||||
const checkOverseerrMerge = async (dbConnection: DataSource) => {
|
||||
const checkOverseerrMerge = async (): Promise<boolean> => {
|
||||
// Load settings without running migrations
|
||||
const settings = await new Settings().load(undefined, true);
|
||||
|
||||
if (settings.main.mediaServerType) {
|
||||
return; // The application has already been migrated
|
||||
return false; // The application has already been migrated
|
||||
}
|
||||
|
||||
// Add fake migration record to prevent running migrations again
|
||||
// Open the database connection to get the migrations
|
||||
const dbConnection = await dataSource.initialize();
|
||||
const migrations = dbConnection.migrations;
|
||||
await dbConnection.destroy();
|
||||
// We have to replace a migration not working with Overseerr with a custom one
|
||||
try {
|
||||
// Apply a filter to replace the specific migration
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
const newMigrations: MixedList<string | Function> = migrations?.map(
|
||||
(migration) =>
|
||||
migration.name === 'AddUserAvatarCacheFields1743107645301'
|
||||
? AddUserAvatarCacheFields1743107645301
|
||||
: migration.constructor
|
||||
);
|
||||
dataSource.setOptions({
|
||||
...dataSource.options,
|
||||
migrations: newMigrations,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to load migrations for Overseerr merge', {
|
||||
label: 'Seerr Migration',
|
||||
error: error.message,
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
// Reopen the database connection with the updated migrations
|
||||
await dataSource.initialize();
|
||||
|
||||
// Add fake migration record to prevent running the already existing Overseerr migration again
|
||||
try {
|
||||
await dbConnection.query(
|
||||
`INSERT INTO migrations (timestamp,name) VALUES (1743023610704, 'UpdateWebPush1743023610704')`
|
||||
@@ -23,20 +51,17 @@ const checkOverseerrMerge = async (dbConnection: DataSource) => {
|
||||
'Failed to insert migration record for UpdateWebPush1743023610704',
|
||||
{
|
||||
label: 'Seerr Migration',
|
||||
message: error.message,
|
||||
error: error.message,
|
||||
}
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Set media server type to Plex (default for Overseerr)
|
||||
settings.main.mediaServerType = MediaServerType.PLEX;
|
||||
|
||||
// Replace default Overseerr values with Seerr values
|
||||
if (settings.main.applicationTitle === 'Overseerr') {
|
||||
settings.main.applicationTitle = 'Seerr';
|
||||
}
|
||||
if (settings.notifications.agents.email.options.senderName === 'Overseerr') {
|
||||
settings.notifications.agents.email.options.senderName = 'Seerr';
|
||||
// Manually run the migration to update the database schema
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
await dbConnection.query('PRAGMA foreign_keys=OFF');
|
||||
await dbConnection.runMigrations();
|
||||
await dbConnection.query('PRAGMA foreign_keys=ON');
|
||||
}
|
||||
|
||||
// MediaStatus.Blacklisted was added before MediaStatus.Deleted in Jellyseerr
|
||||
@@ -50,22 +75,52 @@ const checkOverseerrMerge = async (dbConnection: DataSource) => {
|
||||
} catch (error) {
|
||||
logger.error('Failed to update Media status from Blacklisted to Deleted', {
|
||||
label: 'Seerr Migration',
|
||||
message: error.message,
|
||||
error: error.message,
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Save updated settings
|
||||
// Set media server type to Plex (default for Overseerr)
|
||||
settings.main.mediaServerType = MediaServerType.PLEX;
|
||||
|
||||
// Replace default Overseerr values with Seerr values
|
||||
if (settings.main.applicationTitle === 'Overseerr') {
|
||||
settings.main.applicationTitle = 'Seerr';
|
||||
}
|
||||
if (settings.notifications.agents.email.options.senderName === 'Overseerr') {
|
||||
settings.notifications.agents.email.options.senderName = 'Seerr';
|
||||
}
|
||||
|
||||
// Save the updated settings
|
||||
try {
|
||||
await settings.save();
|
||||
logger.info('Successfully migrated Overseerr to Seerr', {
|
||||
label: 'Seerr Migration',
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to save updated settings after Overseerr migration', {
|
||||
logger.error('Failed to save updated settings for Overseerr merge', {
|
||||
label: 'Seerr Migration',
|
||||
message: error.message,
|
||||
error: error.message,
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
logger.info('Yeah! Overseerr to Seerr migration completed successfully!', {
|
||||
label: 'Seerr Migration',
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
class AddUserAvatarCacheFields1743107645301 implements MigrationInterface {
|
||||
name = 'AddUserAvatarCacheFields1743107645301';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "user" ADD "avatarETag" varchar`);
|
||||
await queryRunner.query(`ALTER TABLE "user" ADD "avatarVersion" varchar`);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export default checkOverseerrMerge;
|
||||
|
||||
Reference in New Issue
Block a user