From 2db47b3335504fb7b6b2833b459bdce6537ab501 Mon Sep 17 00:00:00 2001 From: andres Date: Tue, 12 Mar 2024 16:21:13 +0100 Subject: [PATCH] wip --- prisma/schema.prisma | 6 +- .../decks/infrastructure/decks.repository.ts | 66 +++++++++++++------ src/prisma.service.ts | 46 ++++++------- 3 files changed, 73 insertions(+), 45 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3871388..f1504a7 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,6 +1,8 @@ datasource db { - provider = "mysql" + provider = "postgresql" url = env("DATABASE_URL") + // uncomment next line if you use Prisma <5.10 + directUrl = env("DATABASE_URL_UNPOOLED") relationMode = "prisma" } @@ -42,8 +44,6 @@ model user { revokedToken revokedToken[] RefreshToken refreshToken[] resetPassword resetPassword? - - @@fulltext([name, email]) } model revokedToken { diff --git a/src/modules/decks/infrastructure/decks.repository.ts b/src/modules/decks/infrastructure/decks.repository.ts index 403471d..56834e4 100644 --- a/src/modules/decks/infrastructure/decks.repository.ts +++ b/src/modules/decks/infrastructure/decks.repository.ts @@ -59,7 +59,7 @@ export class DecksRepository { async findMinMaxCards(): Promise<{ min: number; max: number }> { const result = await this.prisma - .$queryRaw`SELECT MAX(card_count) as maxCardsCount, MIN(card_count) as minCardsCount FROM (SELECT deck.id, COUNT(card.id) as card_count FROM deck LEFT JOIN card ON deck.id = card.deckId GROUP BY deck.id) AS card_counts;` + .$queryRaw`SELECT MAX(card_count) as maxCardsCount, MIN(card_count) as minCardsCount FROM (SELECT deck.id, COUNT(card.id) as card_count FROM deck LEFT JOIN card ON deck.id = card."deckId" GROUP BY deck.id) AS card_counts;` return { max: Number(result[0].maxCardsCount), @@ -111,9 +111,10 @@ export class DecksRepository { // Prepare the where clause conditions const conditions = [] - if (name) conditions.push(`d.name LIKE CONCAT('%', ?, '%')`) - if (authorId) conditions.push(`d.userId = ?`) - if (userId) conditions.push(`(d.isPrivate = FALSE OR (d.isPrivate = TRUE AND d.userId = ?))`) + if (name) conditions.push(`d.name LIKE ('%' || ? || '%')`) + if (authorId) conditions.push(`d."userId" = ?`) + if (userId) + conditions.push(`(d."isPrivate" = FALSE OR (d."isPrivate" = TRUE AND d."userId" = ?))`) // Prepare the having clause for card count range const havingConditions = [] @@ -123,19 +124,32 @@ export class DecksRepository { // Construct the raw SQL query for fetching decks const query = ` - SELECT - d.*, - COUNT(c.id) AS cardsCount, - a.id AS authorId, - a.name AS authorName - FROM deck AS d - LEFT JOIN card AS c ON d.id = c.deckId - LEFT JOIN user AS a ON d.userId = a.id - ${conditions.length ? `WHERE ${conditions.join(' AND ')}` : ''} - GROUP BY d.id - ${havingConditions.length ? `HAVING ${havingConditions.join(' AND ')}` : ''} - ORDER BY ${orderField} ${orderDirection} - LIMIT ? OFFSET ?; +SELECT + d.*, + COUNT(c.id) AS "cardsCount", + a."id" AS "authorId", + a."name" AS "authorName" +FROM deck AS "d" +LEFT JOIN "card" AS c ON d."id" = c."deckId" +LEFT JOIN "user" AS a ON d."userId" = a.id +${ + conditions.length + ? `WHERE ${conditions.map((_, index) => `${_.replace('?', `$${index + 1}`)}`).join(' AND ')}` + : '' +} +GROUP BY d."id", a."id" +${ + havingConditions.length + ? `HAVING ${havingConditions + .map((_, index) => `${_.replace('?', `$${conditions.length + index + 1}`)}`) + .join(' AND ')}` + : '' +} +ORDER BY ${orderField} ${orderDirection} +LIMIT $${conditions.length + havingConditions.length + 1} OFFSET $${ + conditions.length + havingConditions.length + 2 + }; + ` // Parameters for fetching decks @@ -164,10 +178,22 @@ export class DecksRepository { FROM ( SELECT d.id FROM deck AS d - LEFT JOIN card AS c ON d.id = c.deckId - ${conditions.length ? `WHERE ${conditions.join(' AND ')}` : ''} + LEFT JOIN card AS c ON d.id = c."deckId" + ${ + conditions.length + ? `WHERE ${conditions + .map((_, index) => `${_.replace('?', `$${index + 1}`)}`) + .join(' AND ')}` + : '' + } GROUP BY d.id - ${havingConditions.length ? `HAVING ${havingConditions.join(' AND ')}` : ''} + ${ + havingConditions.length + ? `HAVING ${havingConditions + .map((_, index) => `${_.replace('?', `$${conditions.length + index + 1}`)}`) + .join(' AND ')}` + : '' + } ) AS subquery; ` diff --git a/src/prisma.service.ts b/src/prisma.service.ts index c547d25..2e023b3 100644 --- a/src/prisma.service.ts +++ b/src/prisma.service.ts @@ -3,37 +3,39 @@ import { PrismaClient } from '@prisma/client' @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { - // constructor() { - // super({ - // log: [ - // { - // emit: 'stdout', - // level: 'query', - // }, - // { - // emit: 'stdout', - // level: 'error', - // }, - // { - // emit: 'stdout', - // level: 'info', - // }, - // { - // emit: 'stdout', - // level: 'warn', - // }, - // ], - // }) - // } + constructor() { + super({ + log: [ + { + emit: 'stdout', + level: 'query', + }, + { + emit: 'stdout', + level: 'error', + }, + { + emit: 'stdout', + level: 'info', + }, + { + emit: 'stdout', + level: 'warn', + }, + ], + }) + } async onModuleInit() { await this.$connect() } + private exitHandler(app: INestApplication) { return async () => { await app.close() } } + async enableShutdownHooks(app: INestApplication) { process.on('exit', this.exitHandler(app)) process.on('beforeExit', this.exitHandler(app))