Moving the arttags table to tags table part 2
This commit is contained in:
@ -13,7 +13,6 @@ export async function deleteArtwork(artworkId: string) {
|
||||
colors: true,
|
||||
metadata: true,
|
||||
tags: true,
|
||||
tagsV2: true,
|
||||
categories: true,
|
||||
},
|
||||
});
|
||||
@ -75,7 +74,6 @@ export async function deleteArtwork(artworkId: string) {
|
||||
where: { id: artworkId },
|
||||
data: {
|
||||
tags: { set: [] },
|
||||
tagsV2: { set: [] },
|
||||
categories: { set: [] },
|
||||
},
|
||||
});
|
||||
|
||||
@ -15,7 +15,7 @@ export async function getSingleArtwork(id: string) {
|
||||
categories: true,
|
||||
colors: { include: { color: true } },
|
||||
// sortContexts: true,
|
||||
tagsV2: true,
|
||||
tags: true,
|
||||
variants: true,
|
||||
timelapse: true
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ function mapSortingToOrderBy(sorting: ArtworkTableInput["sorting"]) {
|
||||
// relation counts: Prisma supports ordering by _count
|
||||
albumsCount: (desc) => ({ albums: { _count: desc ? "desc" : "asc" } }),
|
||||
categoriesCount: (desc) => ({ categories: { _count: desc ? "desc" : "asc" } }),
|
||||
tagsCount: (desc) => ({ tagsV2: { _count: desc ? "desc" : "asc" } }),
|
||||
tagsCount: (desc) => ({ tags: { _count: desc ? "desc" : "asc" } }),
|
||||
};
|
||||
|
||||
const orderBy = sorting
|
||||
@ -89,7 +89,7 @@ export async function getArtworksTablePage(input: unknown) {
|
||||
gallery: { select: { id: true, name: true } },
|
||||
albums: { select: { id: true, name: true } },
|
||||
categories: { select: { id: true, name: true } },
|
||||
_count: { select: { albums: true, categories: true, tagsV2: true } },
|
||||
_count: { select: { albums: true, categories: true, tags: true } },
|
||||
},
|
||||
}),
|
||||
]);
|
||||
@ -109,7 +109,7 @@ export async function getArtworksTablePage(input: unknown) {
|
||||
categories: a.categories,
|
||||
albumsCount: a._count.albums,
|
||||
categoriesCount: a._count.categories,
|
||||
tagsCount: a._count.tagsV2,
|
||||
tagsCount: a._count.tags,
|
||||
}));
|
||||
|
||||
const out = { rows, total, pageIndex, pageSize };
|
||||
|
||||
@ -47,7 +47,7 @@ export async function updateArtwork(
|
||||
const tagsRelation =
|
||||
tagIds || tagsToCreate.length
|
||||
? {
|
||||
tagsV2: {
|
||||
tags: {
|
||||
set: [], // replace entire relation
|
||||
connect: (tagIds ?? []).map((tagId) => ({ id: tagId })),
|
||||
connectOrCreate: tagsToCreate.map((tName) => ({
|
||||
|
||||
@ -1,102 +1,5 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function migrateArtTags() {
|
||||
const artTags = await prisma.artTag.findMany({
|
||||
include: {
|
||||
aliases: true,
|
||||
categories: true,
|
||||
artworks: { select: { id: true } },
|
||||
},
|
||||
orderBy: [{ sortIndex: "asc" }, { name: "asc" }],
|
||||
});
|
||||
|
||||
const idMap = new Map<string, string>();
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
for (const artTag of artTags) {
|
||||
const tag = await tx.tag.upsert({
|
||||
where: { slug: artTag.slug },
|
||||
update: {
|
||||
name: artTag.name,
|
||||
description: artTag.description,
|
||||
isVisible: true,
|
||||
},
|
||||
create: {
|
||||
name: artTag.name,
|
||||
slug: artTag.slug,
|
||||
description: artTag.description,
|
||||
isVisible: true,
|
||||
},
|
||||
});
|
||||
|
||||
idMap.set(artTag.id, tag.id);
|
||||
}
|
||||
|
||||
const aliasRows = artTags.flatMap((artTag) => {
|
||||
const tagId = idMap.get(artTag.id);
|
||||
if (!tagId) return [];
|
||||
return artTag.aliases.map((a) => ({
|
||||
tagId,
|
||||
alias: a.alias,
|
||||
}));
|
||||
});
|
||||
|
||||
if (aliasRows.length > 0) {
|
||||
await tx.tagAlias.createMany({
|
||||
data: aliasRows,
|
||||
skipDuplicates: true,
|
||||
});
|
||||
}
|
||||
|
||||
const categoryRows = artTags.flatMap((artTag) => {
|
||||
const tagId = idMap.get(artTag.id);
|
||||
if (!tagId) return [];
|
||||
const parentTagId = artTag.parentId
|
||||
? idMap.get(artTag.parentId) ?? null
|
||||
: null;
|
||||
|
||||
return artTag.categories.map((category) => ({
|
||||
tagId,
|
||||
categoryId: category.id,
|
||||
isParent: artTag.isParent,
|
||||
showOnAnimalPage: artTag.showOnAnimalPage,
|
||||
parentTagId,
|
||||
}));
|
||||
});
|
||||
|
||||
if (categoryRows.length > 0) {
|
||||
await tx.tagCategory.createMany({
|
||||
data: categoryRows,
|
||||
skipDuplicates: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Connect artwork relations outside the transaction to avoid timeouts.
|
||||
for (const artTag of artTags) {
|
||||
const tagId = idMap.get(artTag.id);
|
||||
if (!tagId) continue;
|
||||
|
||||
for (const artwork of artTag.artworks) {
|
||||
await prisma.artwork.update({
|
||||
where: { id: artwork.id },
|
||||
data: {
|
||||
tagsV2: {
|
||||
connect: { id: tagId },
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const summary = {
|
||||
tags: artTags.length,
|
||||
aliases: artTags.reduce((sum, t) => sum + t.aliases.length, 0),
|
||||
categoryLinks: artTags.reduce((sum, t) => sum + t.categories.length, 0),
|
||||
};
|
||||
revalidatePath("/tags");
|
||||
return summary;
|
||||
throw new Error("Migration disabled: ArtTag models removed.");
|
||||
}
|
||||
|
||||
75
src/actions/tags/migrateArtworkTagJoin.ts
Normal file
75
src/actions/tags/migrateArtworkTagJoin.ts
Normal file
@ -0,0 +1,75 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
type JoinMigrationResult = {
|
||||
ok: boolean;
|
||||
copied: number;
|
||||
oldExists: boolean;
|
||||
newExists: boolean;
|
||||
droppedOld: boolean;
|
||||
message?: string;
|
||||
};
|
||||
|
||||
export async function migrateArtworkTagJoin(
|
||||
opts: { dropOld?: boolean } = {},
|
||||
): Promise<JoinMigrationResult> {
|
||||
const dropOld = Boolean(opts.dropOld);
|
||||
|
||||
const [oldRow, newRow] = await Promise.all([
|
||||
prisma.$queryRaw<{ name: string | null }[]>`
|
||||
select to_regclass('_ArtworkTagsV2')::text as name;
|
||||
`,
|
||||
prisma.$queryRaw<{ name: string | null }[]>`
|
||||
select to_regclass('_ArtworkTags')::text as name;
|
||||
`,
|
||||
]);
|
||||
|
||||
const oldExists = Boolean(oldRow?.[0]?.name);
|
||||
const newExists = Boolean(newRow?.[0]?.name);
|
||||
|
||||
if (!newExists) {
|
||||
return {
|
||||
ok: false,
|
||||
copied: 0,
|
||||
oldExists,
|
||||
newExists,
|
||||
droppedOld: false,
|
||||
message: "New join table _ArtworkTags does not exist. Run the migration first.",
|
||||
};
|
||||
}
|
||||
|
||||
if (!oldExists) {
|
||||
return {
|
||||
ok: true,
|
||||
copied: 0,
|
||||
oldExists,
|
||||
newExists,
|
||||
droppedOld: false,
|
||||
message: "Old join table _ArtworkTagsV2 not found. Nothing to copy.",
|
||||
};
|
||||
}
|
||||
|
||||
const copied = await prisma.$executeRawUnsafe(`
|
||||
INSERT INTO "_ArtworkTags" ("A","B")
|
||||
SELECT "A","B" FROM "_ArtworkTagsV2"
|
||||
ON CONFLICT ("A","B") DO NOTHING;
|
||||
`);
|
||||
|
||||
let droppedOld = false;
|
||||
if (dropOld) {
|
||||
await prisma.$executeRawUnsafe(`DROP TABLE "_ArtworkTagsV2";`);
|
||||
droppedOld = true;
|
||||
}
|
||||
|
||||
revalidatePath("/tags");
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
copied: Number(copied ?? 0),
|
||||
oldExists,
|
||||
newExists,
|
||||
droppedOld,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user