boredgame/src/lib/utils/dbUtils.ts

445 lines
11 KiB
TypeScript
Raw Normal View History

2023-10-16 02:42:34 +00:00
import type { Game } from '@prisma/client';
import kebabCase from 'just-kebab-case';
import type { BggLinkDto } from 'boardgamegeekclient/dist/esm/dto/concrete/subdto';
import prisma from '$lib/prisma';
2023-10-16 02:42:34 +00:00
import { mapAPIGameToBoredGame } from './gameMapper';
import db from '$lib/drizzle';
import { games } from '../../schema';
import { eq, sql } from 'drizzle-orm';
export async function createArtist(locals: App.Locals, externalArtist: BggLinkDto) {
try {
let dbArtist = await prisma.artist.findFirst({
where: {
external_id: externalArtist.id
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
if (dbArtist) {
console.log('Artist already exists', dbArtist.name);
return dbArtist;
}
console.log('Creating artist', JSON.stringify(externalArtist, null, 2));
let artist = await prisma.artist.create({
data: {
name: externalArtist.value,
external_id: externalArtist.id,
slug: kebabCase(externalArtist.value)
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
console.log('Created artist', JSON.stringify(artist, null, 2));
return artist;
} catch (e) {
console.error(e);
throw new Error('Something went wrong creating Artist');
}
}
export async function createDesigner(locals: App.Locals, externalDesigner: BggLinkDto) {
try {
let dbDesigner = await prisma.designer.findFirst({
where: {
external_id: externalDesigner.id
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
if (dbDesigner) {
console.log('Designer already exists', dbDesigner.name);
return dbDesigner;
}
console.log('Creating designer', JSON.stringify(externalDesigner, null, 2));
let designer = await prisma.designer.create({
data: {
name: externalDesigner.value,
external_id: externalDesigner.id,
slug: kebabCase(externalDesigner.value)
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
console.log('Created designer', JSON.stringify(designer, null, 2));
return designer;
} catch (e) {
console.error(e);
throw new Error('Something went wrong creating Designer');
}
}
export async function createPublisher(locals: App.Locals, externalPublisher: BggLinkDto) {
try {
let dbPublisher = await prisma.publisher.findFirst({
where: {
external_id: externalPublisher.id
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
if (dbPublisher) {
console.log('Publisher already exists', dbPublisher.name);
return dbPublisher;
}
console.log('Creating publisher', JSON.stringify(externalPublisher, null, 2));
let publisher = await prisma.publisher.create({
data: {
name: externalPublisher.value,
external_id: externalPublisher.id,
slug: kebabCase(externalPublisher.value)
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
console.log('Created publisher', JSON.stringify(publisher, null, 2));
return publisher;
} catch (e) {
console.error(e);
throw new Error('Something went wrong creating Publisher');
}
}
export async function createCategory(locals: App.Locals, externalCategory: BggLinkDto) {
try {
let dbCategory = await prisma.category.findFirst({
where: {
external_id: externalCategory.id
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
if (dbCategory) {
console.log('Category already exists', dbCategory.name);
return dbCategory;
}
console.log('Creating category', JSON.stringify(externalCategory, null, 2));
let category = await prisma.category.create({
data: {
name: externalCategory.value,
external_id: externalCategory.id,
slug: kebabCase(externalCategory.value)
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
console.log('Created category', JSON.stringify(category, null, 2));
return category;
} catch (e) {
console.error(e);
throw new Error('Something went wrong creating Category');
}
}
export async function createMechanic(locals: App.Locals, externalMechanic: BggLinkDto) {
try {
let dbMechanic = await prisma.mechanic.findFirst({
where: {
external_id: externalMechanic.id
},
select: {
id: true,
name: true,
slug: true,
external_id: true
}
});
if (dbMechanic) {
console.log('Mechanic already exists', dbMechanic.name);
return dbMechanic;
}
console.log('Creating mechanic', JSON.stringify(externalMechanic, null, 2));
let mechanic = await prisma.mechanic.upsert({
where: {
external_id: externalMechanic.id
},
create: {
name: externalMechanic.value,
external_id: externalMechanic.id,
slug: kebabCase(externalMechanic.value)
},
update: {
name: externalMechanic.value,
slug: kebabCase(externalMechanic.value)
}
});
console.log('Created mechanic', JSON.stringify(mechanic, null, 2));
return mechanic;
} catch (e) {
console.error(e);
throw new Error('Something went wrong creating Mechanic');
}
}
2023-10-16 02:42:34 +00:00
export async function createExpansion(
locals: App.Locals,
2023-10-16 02:42:34 +00:00
game: Game,
externalExpansion: BggLinkDto,
gameIsExpansion: boolean,
eventFetch: Function
) {
try {
let dbExpansionGame = await prisma.game.findUnique({
where: {
external_id: externalExpansion.id
}
});
if (!dbExpansionGame) {
const externalGameResponse = await eventFetch(
`/api/external/game/${externalExpansion.id}?simplified=true`
);
if (externalGameResponse.ok) {
const externalGame = await externalGameResponse.json();
console.log('externalGame', externalGame);
let boredGame = mapAPIGameToBoredGame(externalGame);
dbExpansionGame = await createOrUpdateGameMinimal(locals, boredGame);
} else {
2023-10-16 02:42:34 +00:00
throw new Error(
`${gameIsExpansion ? 'Base game' : 'Expansion game'} not found and failed to create.`
);
}
}
let dbExpansion;
let baseGameId;
let gameId;
if (gameIsExpansion) {
2023-10-16 02:42:34 +00:00
console.log(
'External expansion is expansion. Looking for base game',
JSON.stringify(game, null, 2)
);
dbExpansion = await prisma.expansion.findFirst({
where: {
game_id: dbExpansionGame.id
},
select: {
id: true,
base_game_id: true,
game_id: true
}
});
baseGameId = game.id;
gameId = dbExpansionGame.id;
} else {
2023-10-16 02:42:34 +00:00
console.log(
'External Expansion is base game. Looking for expansion',
JSON.stringify(game, null, 2)
);
dbExpansion = await prisma.expansion.findFirst({
where: {
base_game_id: dbExpansionGame.id
},
select: {
id: true,
base_game_id: true,
game_id: true
}
});
baseGameId = dbExpansionGame.id;
gameId = game.id;
}
if (dbExpansion) {
console.log('Expansion already exists', JSON.stringify(dbExpansion, null, 2));
return dbExpansion;
}
console.log(`Creating expansion. baseGameId: ${baseGameId}, gameId: ${gameId}`);
let expansion = await prisma.expansion.create({
data: {
base_game_id: baseGameId,
game_id: gameId
}
});
console.log('Created expansion', JSON.stringify(expansion, null, 2));
if (gameIsExpansion) {
console.log('Connecting current game to expansion');
await prisma.game.update({
where: {
id: gameId
},
data: {
expansions: {
connect: {
id: expansion.id
}
}
}
});
} else {
console.log('Connecting current game to base game');
await prisma.game.update({
where: {
id: baseGameId
},
data: {
expansions: {
connect: {
id: expansion.id
}
}
}
});
}
return expansion;
} catch (e) {
console.error(e);
throw new Error('Something went wrong creating Expansion');
}
}
export async function createOrUpdateGameMinimal(locals: App.Locals, game: Game) {
console.log('Creating or updating minimal game data', JSON.stringify(game, null, 2));
const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`;
await db.insert(games).values({
external_id: game.external_id,
name: game.name,
slug: kebabCase(game.name),
description: game.description,
url: externalUrl,
thumb_url: game.thumb_url,
image_url: game.image_url,
min_age: game.min_age || 0,
min_players: game.min_players || 0,
max_players: game.max_players || 0,
min_playtime: game.min_playtime || 0,
max_playtime: game.max_playtime || 0,
year_published: game.year_published || 0,
}).onDuplicateKeyUpdate({ set: { external_id: sql`external_id` } });
return db.query.games.findFirst({ where: eq(games.external_id, game.external_id) });
}
export async function createOrUpdateGame(locals: App.Locals, game: Game) {
console.log('Creating or updating game', JSON.stringify(game, null, 2));
const categoryIds = game.categories;
const mechanicIds = game.mechanics;
const publisherIds = game.publishers;
const designerIds = game.designers;
const artistIds = game.artists;
// const expansionIds = game.expansions;
const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`;
console.log('categoryIds', categoryIds);
console.log('mechanicIds', mechanicIds);
await db.transaction(async (transaction) => {
const
});
await db.insert(games).values({
include: {
mechanics: true,
publishers: true,
designers: true,
artists: true,
expansions: true
},
where: {
external_id: game.external_id
},
create: {
name: game.name,
slug: kebabCase(game.name),
description: game.description,
external_id: game.external_id,
url: externalUrl,
thumb_url: game.thumb_url,
image_url: game.image_url,
min_age: game.min_age || 0,
min_players: game.min_players || 0,
max_players: game.max_players || 0,
min_playtime: game.min_playtime || 0,
max_playtime: game.max_playtime || 0,
year_published: game.year_published || 0,
last_sync_at: new Date(),
categories: {
connect: categoryIds
},
mechanics: {
connect: mechanicIds
},
publishers: {
connect: publisherIds
},
designers: {
connect: designerIds
},
artists: {
connect: artistIds
}
},
update: {
name: game.name,
slug: kebabCase(game.name),
description: game.description,
external_id: game.external_id,
url: externalUrl,
thumb_url: game.thumb_url,
image_url: game.image_url,
min_age: game.min_age || 0,
min_players: game.min_players || 0,
max_players: game.max_players || 0,
min_playtime: game.min_playtime || 0,
max_playtime: game.max_playtime || 0,
year_published: game.year_published || 0,
last_sync_at: new Date(),
categories: {
connect: categoryIds
},
mechanics: {
connect: mechanicIds
},
publishers: {
connect: publisherIds
},
designers: {
connect: designerIds
},
artists: {
connect: artistIds
}
}
});
}