wip: upsert things

This commit is contained in:
Zoe Roux
2024-11-30 04:56:53 +01:00
parent 3d20f063e9
commit 55b3f1cc8c
7 changed files with 969 additions and 1 deletions
+11
View File
@@ -0,0 +1,11 @@
import { db } from "~/db";
import { videos } from "~/db/schema";
import { bubble, bubbleVideo } from "~/models/examples";
import { seedMovie } from "./movies";
const videoExamples = [bubbleVideo];
export const seedTests = async () => {
await db.insert(videos).values(videoExamples).onConflictDoNothing();
await seedMovie(bubble)
};
+27 -1
View File
@@ -39,7 +39,28 @@ export const seedMovie = async (
const [ret] = await tx
.insert(shows)
.values(movie)
.returning({ pk: shows.pk, id: shows.id, slug: shows.slug });
.onConflictDoUpdate({
target: shows.slug,
// we actually don't want to update anything, but we want to return the existing row.
// using a conflict update with a where false locks the database and ensure we don't have race conditions.
// it WONT work if we use triggers or need to handle conflicts on multiples collumns
// see https://stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql for more
set: { id: sql`excluded.id` },
setWhere: sql`false`,
})
.returning({
pk: shows.pk,
id: shows.id,
slug: shows.slug,
startAir: shows.startAir,
// https://stackoverflow.com/questions/39058213/differentiate-inserted-and-updated-rows-in-upsert-using-system-columns/39204667#39204667
conflict: sql`xmax = 0`.as("conflict"),
});
if (ret.conflict) {
if (getYear(ret.startAir) === getYear(movie.startAir)) {
return
}
}
// even if never shown to the user, a movie still has an entry.
const movieEntry: Entry = { type: "movie", ...bMovie };
@@ -102,3 +123,8 @@ export const seedMovie = async (
videos: retVideos,
};
};
function getYear(date?: string | null) {
if (!date) return null;
return new Date(date).getUTCFullYear();
}