Reduce source requests during bulk migration
During the search the destination entries are already freshly fetched. Thus, this is not necessary anymore during the actual migration
This commit is contained in:
@@ -126,7 +126,7 @@ export const MangaCard = memo((props: MangaCardProps) => {
|
||||
|
||||
try {
|
||||
try {
|
||||
await MangaMigration.migrate(migrationSourceMangaId, id, options);
|
||||
await MangaMigration.migrateByIdWithFetch(migrationSourceMangaId, id, options);
|
||||
} catch (e) {
|
||||
makeToast(
|
||||
t(MANGA_ACTION_TO_TRANSLATION['migrate'].error),
|
||||
|
||||
@@ -14,13 +14,28 @@ import type {
|
||||
} from '@/lib/graphql/generated/graphql.ts';
|
||||
import type { MangaIdInfo } from '@/features/manga/Manga.types.ts';
|
||||
import { Chapters } from '@/features/chapter/services/Chapters.ts';
|
||||
import { getMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts';
|
||||
import { ALL_APP_METADATA_KEY_PREFIXES } from '@/features/metadata/Metadata.constants.ts';
|
||||
import type { MigrateMode, MigrateOptions } from '@/features/migration/Migration.types.ts';
|
||||
import type {
|
||||
ChapterBookmarkInfo,
|
||||
ChapterDownloadInfo,
|
||||
ChapterIdInfo,
|
||||
ChapterNumberInfo,
|
||||
ChapterReadInfo,
|
||||
} from '@/features/chapter/Chapter.types.ts';
|
||||
import type { GqlMetaHolder } from '@/features/metadata/Metadata.types.ts';
|
||||
import { getMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts';
|
||||
|
||||
type MangaToMigrate = NonNullable<GetMangaToMigrateQuery['manga']>;
|
||||
type MangaToMigrateTo = NonNullable<GetMangaToMigrateToFetchMutation['fetchManga']>['manga'];
|
||||
|
||||
export type MigrationChapter = ChapterIdInfo &
|
||||
ChapterReadInfo &
|
||||
ChapterBookmarkInfo &
|
||||
ChapterNumberInfo &
|
||||
ChapterDownloadInfo &
|
||||
GqlMetaHolder;
|
||||
|
||||
type MigrateAction = { copy: () => Promise<unknown>[]; cleanup: () => Promise<unknown>[] };
|
||||
type MigrateActionCreator = () => MigrateAction;
|
||||
|
||||
@@ -29,8 +44,9 @@ const performMigrationAction = async (migrateAction: keyof MigrateAction, ...act
|
||||
|
||||
export class MangaMigration {
|
||||
static async migrate(
|
||||
mangaId: MangaIdInfo['id'],
|
||||
mangaIdToMigrateTo: number,
|
||||
mangaToMigrate: MangaToMigrate | null | undefined,
|
||||
mangaToMigrateTo: MangaToMigrateTo | null | undefined,
|
||||
chaptersToMigrateTo: MigrationChapter[] | null | undefined,
|
||||
{
|
||||
mode,
|
||||
migrateChapters,
|
||||
@@ -39,37 +55,16 @@ export class MangaMigration {
|
||||
deleteChapters,
|
||||
migrateMetadata,
|
||||
}: Omit<MigrateOptions, 'mangaIdToMigrateTo'>,
|
||||
removeMangaFromCategories: boolean,
|
||||
): Promise<void> {
|
||||
const [{ data: mangaToMigrateData }, { data: mangaToMigrateToData }, { removeMangaFromCategories }] =
|
||||
await Promise.all([
|
||||
requestManager.getMangaToMigrate(mangaId, {
|
||||
migrateChapters,
|
||||
migrateCategories,
|
||||
migrateTracking,
|
||||
deleteChapters,
|
||||
migrateMetadata,
|
||||
}).response,
|
||||
requestManager.getMangaToMigrateToFetch(mangaIdToMigrateTo, {
|
||||
migrateChapters,
|
||||
migrateCategories,
|
||||
migrateTracking,
|
||||
apolloOptions: { errorPolicy: 'all' },
|
||||
}).response,
|
||||
getMetadataServerSettings(),
|
||||
]);
|
||||
|
||||
if (!mangaToMigrateData?.manga || !mangaToMigrateToData?.fetchManga?.manga) {
|
||||
if (!mangaToMigrate || !mangaToMigrateTo) {
|
||||
throw new Error('MangaMigration::migrate: missing manga data');
|
||||
}
|
||||
|
||||
if (migrateChapters && !mangaToMigrateData.manga.chapters) {
|
||||
if (migrateChapters && !mangaToMigrate.chapters) {
|
||||
throw new Error('MangaMigration::migrate: missing chapters data');
|
||||
}
|
||||
|
||||
if (!mangaToMigrateToData.fetchChapters?.chapters) {
|
||||
mangaToMigrateToData.fetchChapters = { chapters: [] };
|
||||
}
|
||||
|
||||
const performMigrationActions = async (...actionCreators: [boolean | undefined, MigrateActionCreator][]) => {
|
||||
const migrationActions: TupleUnion<keyof MigrateAction> = ['copy', 'cleanup'];
|
||||
|
||||
@@ -92,28 +87,20 @@ export class MangaMigration {
|
||||
() =>
|
||||
MangaMigration.migrateChapters(
|
||||
mode,
|
||||
mangaToMigrateData.manga,
|
||||
mangaToMigrateToData,
|
||||
mangaToMigrate.chapters?.nodes,
|
||||
chaptersToMigrateTo,
|
||||
!!deleteChapters,
|
||||
!!migrateMetadata,
|
||||
),
|
||||
],
|
||||
[
|
||||
migrateTracking,
|
||||
() =>
|
||||
MangaMigration.migrateTracking(
|
||||
mode,
|
||||
mangaToMigrateData.manga,
|
||||
mangaToMigrateToData.fetchManga!.manga,
|
||||
),
|
||||
],
|
||||
[migrateTracking, () => MangaMigration.migrateTracking(mode, mangaToMigrate, mangaToMigrateTo)],
|
||||
[
|
||||
true,
|
||||
() =>
|
||||
MangaMigration.migrateManga(
|
||||
mode,
|
||||
mangaToMigrateData.manga,
|
||||
mangaToMigrateToData.fetchManga!.manga,
|
||||
mangaToMigrate,
|
||||
mangaToMigrateTo,
|
||||
!!migrateCategories,
|
||||
removeMangaFromCategories,
|
||||
!!migrateMetadata,
|
||||
@@ -122,20 +109,86 @@ export class MangaMigration {
|
||||
);
|
||||
}
|
||||
|
||||
static async migrateByIdWithQuery(
|
||||
mangaId: MangaIdInfo['id'],
|
||||
mangaIdToMigrateTo: number,
|
||||
options: Omit<MigrateOptions, 'mangaIdToMigrateTo'>,
|
||||
): Promise<void> {
|
||||
const { migrateChapters, migrateCategories, migrateTracking, deleteChapters, migrateMetadata } = options;
|
||||
|
||||
const [{ data: mangaToMigrateData }, { data: mangaToMigrateToData }, { removeMangaFromCategories }] =
|
||||
await Promise.all([
|
||||
requestManager.getMangaToMigrate(mangaId, {
|
||||
migrateChapters,
|
||||
migrateCategories,
|
||||
migrateTracking,
|
||||
deleteChapters,
|
||||
migrateMetadata,
|
||||
}).response,
|
||||
requestManager.getMangaToMigrate(mangaIdToMigrateTo, {
|
||||
migrateChapters,
|
||||
migrateCategories,
|
||||
migrateTracking,
|
||||
deleteChapters,
|
||||
migrateMetadata,
|
||||
}).response,
|
||||
getMetadataServerSettings(),
|
||||
]);
|
||||
|
||||
await MangaMigration.migrate(
|
||||
mangaToMigrateData?.manga,
|
||||
mangaToMigrateToData?.manga,
|
||||
mangaToMigrateToData?.manga?.chapters?.nodes,
|
||||
options,
|
||||
removeMangaFromCategories,
|
||||
);
|
||||
}
|
||||
|
||||
static async migrateByIdWithFetch(
|
||||
mangaId: MangaIdInfo['id'],
|
||||
mangaIdToMigrateTo: number,
|
||||
options: Omit<MigrateOptions, 'mangaIdToMigrateTo'>,
|
||||
): Promise<void> {
|
||||
const { migrateChapters, migrateCategories, migrateTracking, deleteChapters, migrateMetadata } = options;
|
||||
|
||||
const [{ data: mangaToMigrateData }, { data: mangaToMigrateToData }, { removeMangaFromCategories }] =
|
||||
await Promise.all([
|
||||
requestManager.getMangaToMigrate(mangaId, {
|
||||
migrateChapters,
|
||||
migrateCategories,
|
||||
migrateTracking,
|
||||
deleteChapters,
|
||||
migrateMetadata,
|
||||
}).response,
|
||||
requestManager.getMangaToMigrateToFetch(mangaIdToMigrateTo, {
|
||||
migrateChapters,
|
||||
migrateCategories,
|
||||
migrateTracking,
|
||||
apolloOptions: { errorPolicy: 'all' },
|
||||
}).response,
|
||||
getMetadataServerSettings(),
|
||||
]);
|
||||
|
||||
await MangaMigration.migrate(
|
||||
mangaToMigrateData?.manga,
|
||||
mangaToMigrateToData?.fetchManga?.manga,
|
||||
mangaToMigrateToData?.fetchChapters?.chapters,
|
||||
options,
|
||||
removeMangaFromCategories,
|
||||
);
|
||||
}
|
||||
|
||||
private static migrateChapters(
|
||||
mode: MigrateMode,
|
||||
mangaToMigrate: GetMangaToMigrateQuery['manga'],
|
||||
mangaToMigrateToInfo: GetMangaToMigrateToFetchMutation,
|
||||
chaptersToMigrate: MigrationChapter[] | null | undefined,
|
||||
chaptersToMigrateTo: MigrationChapter[] | null | undefined,
|
||||
deleteChapters: boolean,
|
||||
migrateMetadata: boolean,
|
||||
): MigrateAction {
|
||||
if (!mangaToMigrate.chapters || !mangaToMigrateToInfo.fetchChapters?.chapters) {
|
||||
if (!chaptersToMigrate || !chaptersToMigrateTo) {
|
||||
throw new Error('Chapters are missing');
|
||||
}
|
||||
|
||||
const chaptersToMigrate = mangaToMigrate.chapters.nodes;
|
||||
|
||||
const chaptersToMigrateTo = mangaToMigrateToInfo.fetchChapters?.chapters;
|
||||
const migratableChapters = Chapters.getMatchingChapterNumberChapters(chaptersToMigrate, chaptersToMigrateTo);
|
||||
|
||||
const highestReadChapterNumber = chaptersToMigrate.reduce((chapterNumber, chapterToMigrate) => {
|
||||
@@ -197,7 +250,7 @@ export class MangaMigration {
|
||||
? [
|
||||
deleteChapters
|
||||
? requestManager.deleteDownloadedChapters(
|
||||
Chapters.getIds(Chapters.getDownloaded(mangaToMigrate.chapters?.nodes ?? [])),
|
||||
Chapters.getIds(Chapters.getDownloaded(chaptersToMigrate)),
|
||||
).response
|
||||
: Promise.resolve(),
|
||||
]
|
||||
|
||||
@@ -963,7 +963,8 @@ export class MigrationManager {
|
||||
}
|
||||
|
||||
assertIsDefined(entry.selectedMatchMangaId);
|
||||
await MangaMigration.migrate(mangaId, entry.selectedMatchMangaId, options);
|
||||
|
||||
await MangaMigration.migrateByIdWithQuery(mangaId, entry.selectedMatchMangaId, options);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user