mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
wip: push movies could update items
This commit is contained in:
parent
55b3f1cc8c
commit
cfe2cabfa4
@ -10,9 +10,10 @@ import {
|
|||||||
import type { SeedMovie } from "~/models/movie";
|
import type { SeedMovie } from "~/models/movie";
|
||||||
import { processOptImage } from "./images";
|
import { processOptImage } from "./images";
|
||||||
import { guessNextRefresh } from "./refresh";
|
import { guessNextRefresh } from "./refresh";
|
||||||
import { inArray, sql } from "drizzle-orm";
|
import { eq, getTableColumns, inArray, sql } from "drizzle-orm";
|
||||||
import { t } from "elysia";
|
import { t } from "elysia";
|
||||||
import { Resource } from "~/models/utils";
|
import { Resource } from "~/models/utils";
|
||||||
|
import { conflictUpdateAllExcept } from "~/db/schema/utils";
|
||||||
|
|
||||||
type Show = typeof shows.$inferInsert;
|
type Show = typeof shows.$inferInsert;
|
||||||
type ShowTrans = typeof showTranslations.$inferInsert;
|
type ShowTrans = typeof showTranslations.$inferInsert;
|
||||||
@ -41,12 +42,9 @@ export const seedMovie = async (
|
|||||||
.values(movie)
|
.values(movie)
|
||||||
.onConflictDoUpdate({
|
.onConflictDoUpdate({
|
||||||
target: shows.slug,
|
target: shows.slug,
|
||||||
// we actually don't want to update anything, but we want to return the existing row.
|
set: conflictUpdateAllExcept(shows, ["pk", "id", "slug", "createdAt"]),
|
||||||
// using a conflict update with a where false locks the database and ensure we don't have race conditions.
|
// if year is different, this is not an update but a conflict (ex: dune-1984 vs dune-2021)
|
||||||
// it WONT work if we use triggers or need to handle conflicts on multiples collumns
|
setWhere: sql`date_part('year', ${shows.startAir}) = date_part('year', excluded."start_air")`,
|
||||||
// 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({
|
.returning({
|
||||||
pk: shows.pk,
|
pk: shows.pk,
|
||||||
@ -54,11 +52,18 @@ export const seedMovie = async (
|
|||||||
slug: shows.slug,
|
slug: shows.slug,
|
||||||
startAir: shows.startAir,
|
startAir: shows.startAir,
|
||||||
// https://stackoverflow.com/questions/39058213/differentiate-inserted-and-updated-rows-in-upsert-using-system-columns/39204667#39204667
|
// https://stackoverflow.com/questions/39058213/differentiate-inserted-and-updated-rows-in-upsert-using-system-columns/39204667#39204667
|
||||||
conflict: sql`xmax = 0`.as("conflict"),
|
updated: sql`(xmax = 0)`.as("updated"),
|
||||||
|
xmin: sql`xmin`,
|
||||||
|
xmax: sql`xmax`,
|
||||||
|
created: shows.createdAt,
|
||||||
});
|
});
|
||||||
if (ret.conflict) {
|
// TODO: the `updated` bool is always false :c
|
||||||
|
console.log(`slug: ${ret.slug}, updated: ${ret.updated}`);
|
||||||
|
console.log(ret)
|
||||||
|
if (ret.updated) {
|
||||||
|
console.log("Updated!");
|
||||||
if (getYear(ret.startAir) === getYear(movie.startAir)) {
|
if (getYear(ret.startAir) === getYear(movie.startAir)) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
View,
|
View,
|
||||||
ViewBaseConfig,
|
ViewBaseConfig,
|
||||||
|
getTableColumns,
|
||||||
|
sql,
|
||||||
|
SQL,
|
||||||
} from "drizzle-orm";
|
} from "drizzle-orm";
|
||||||
import type { AnyMySqlSelect } from "drizzle-orm/mysql-core";
|
import type { AnyMySqlSelect } from "drizzle-orm/mysql-core";
|
||||||
import {
|
import {
|
||||||
@ -15,6 +18,8 @@ import {
|
|||||||
} from "drizzle-orm/pg-core";
|
} from "drizzle-orm/pg-core";
|
||||||
import type { AnySQLiteSelect } from "drizzle-orm/sqlite-core";
|
import type { AnySQLiteSelect } from "drizzle-orm/sqlite-core";
|
||||||
import type { WithSubquery } from "drizzle-orm/subquery";
|
import type { WithSubquery } from "drizzle-orm/subquery";
|
||||||
|
import { db } from "..";
|
||||||
|
import { CasingCache } from "drizzle-orm/casing";
|
||||||
|
|
||||||
export const schema = pgSchema("kyoo");
|
export const schema = pgSchema("kyoo");
|
||||||
|
|
||||||
@ -24,11 +29,13 @@ export const image = () =>
|
|||||||
jsonb().$type<{ id: string; source: string; blurhash: string }>();
|
jsonb().$type<{ id: string; source: string; blurhash: string }>();
|
||||||
|
|
||||||
// https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts#L58
|
// https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts#L58
|
||||||
type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
|
type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
|
||||||
|
|
||||||
// See https://github.com/drizzle-team/drizzle-orm/pull/1789
|
// See https://github.com/drizzle-team/drizzle-orm/pull/1789
|
||||||
type Select = AnyPgSelect | AnyMySqlSelect | AnySQLiteSelect;
|
type Select = AnyPgSelect | AnyMySqlSelect | AnySQLiteSelect;
|
||||||
type AnySelect = Simplify<Omit<Select, "where"> & Partial<Pick<Select, "where">>>;
|
type AnySelect = Simplify<
|
||||||
|
Omit<Select, "where"> & Partial<Pick<Select, "where">>
|
||||||
|
>;
|
||||||
export function getColumns<
|
export function getColumns<
|
||||||
T extends
|
T extends
|
||||||
| Table
|
| Table
|
||||||
@ -49,3 +56,24 @@ export function getColumns<
|
|||||||
? (table as any)[ViewBaseConfig].selectedFields
|
? (table as any)[ViewBaseConfig].selectedFields
|
||||||
: table._.selectedFields;
|
: table._.selectedFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See https://github.com/drizzle-team/drizzle-orm/issues/1728
|
||||||
|
export function conflictUpdateAllExcept<
|
||||||
|
T extends Table,
|
||||||
|
E extends (keyof T["_"]["columns"])[],
|
||||||
|
>(table: T, except: E) {
|
||||||
|
const columns = getTableColumns(table);
|
||||||
|
const updateColumns = Object.entries(columns).filter(
|
||||||
|
([col]) => !except.includes(col),
|
||||||
|
);
|
||||||
|
|
||||||
|
return updateColumns.reduce(
|
||||||
|
(acc, [colName, col]) => {
|
||||||
|
// @ts-ignore: drizzle internal
|
||||||
|
const name = (db.dialect.casing as CasingCache).getColumnCasing(col);
|
||||||
|
acc[colName as keyof typeof acc] = sql.raw(`excluded."${name}"`);
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Omit<Record<keyof T["_"]["columns"], SQL>, E[number]>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user