From 42f837cd2baf65d4311db67afbab07cd843cd59e Mon Sep 17 00:00:00 2001 From: Benjamin Bohec Date: Fri, 7 Jul 2023 16:16:33 +0200 Subject: [PATCH] error logs on PG discussion aggr queries --- .../pg/PgDiscussionAggregateRepository.ts | 224 +++++++----------- 1 file changed, 85 insertions(+), 139 deletions(-) diff --git a/back/src/adapters/secondary/pg/PgDiscussionAggregateRepository.ts b/back/src/adapters/secondary/pg/PgDiscussionAggregateRepository.ts index bf7c5dee37..f507985d79 100644 --- a/back/src/adapters/secondary/pg/PgDiscussionAggregateRepository.ts +++ b/back/src/adapters/secondary/pg/PgDiscussionAggregateRepository.ts @@ -1,4 +1,4 @@ -import { PoolClient } from "pg"; +import { PoolClient, QueryConfig, QueryResult, QueryResultRow } from "pg"; import format from "pg-format"; import { DiscussionId, SiretDto } from "shared"; import { @@ -6,6 +6,9 @@ import { ExchangeEntity, } from "../../../domain/immersionOffer/entities/DiscussionAggregate"; import { DiscussionAggregateRepository } from "../../../domain/immersionOffer/ports/DiscussionAggregateRepository"; +import { createLogger } from "../../../utils/logger"; + +const logger = createLogger(__filename); export class PgDiscussionAggregateRepository implements DiscussionAggregateRepository @@ -13,111 +16,44 @@ export class PgDiscussionAggregateRepository constructor(private client: PoolClient) {} async insert(discussion: DiscussionAggregate) { - await this.client.query( - `INSERT INTO discussions ( - id, - contact_mode, - siret, - appellation_code, - potential_beneficiary_first_name, - potential_beneficiary_last_name, - potential_beneficiary_email, - potential_beneficiary_phone, - immersion_objective, - potential_beneficiary_resume_link, - created_at, - establishment_contact_email, - establishment_contact_first_name, - establishment_contact_last_name, - establishment_contact_phone, - establishment_contact_job, - establishment_contact_copy_emails, - street_number_and_address, - postcode, - department_code, - city, - business_name - ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22)`, - [ - discussion.id, - discussion.establishmentContact.contactMode, - discussion.siret, - discussion.appellationCode, - discussion.potentialBeneficiary.firstName, - discussion.potentialBeneficiary.lastName, - discussion.potentialBeneficiary.email, - discussion.potentialBeneficiary.phone, - discussion.immersionObjective, - discussion.potentialBeneficiary.resumeLink, - discussion.createdAt.toISOString(), - discussion.establishmentContact.email, - discussion.establishmentContact.firstName, - discussion.establishmentContact.lastName, - discussion.establishmentContact.phone, - discussion.establishmentContact.job, - JSON.stringify(discussion.establishmentContact.copyEmails), - discussion.address.streetNumberAndAddress, - discussion.address.postcode, - discussion.address.departmentCode, - discussion.address.city, - discussion.businessName, - ], - ); - + const query = `INSERT INTO discussions ( + id, contact_mode, siret, appellation_code, potential_beneficiary_first_name, + potential_beneficiary_last_name, potential_beneficiary_email, potential_beneficiary_phone, immersion_objective, potential_beneficiary_resume_link, + created_at, establishment_contact_email, establishment_contact_first_name, establishment_contact_last_name, establishment_contact_phone, + establishment_contact_job, establishment_contact_copy_emails, street_number_and_address, postcode, department_code, + city, business_name + ) VALUES ( + $1, $2, $3, $4, $5, + $6, $7, $8, $9, $10, + $11, $12, $13, $14, $15, + $16, $17, $18, $19, $20, + $21, $22 + )`; + // prettier-ignore + const values = [ discussion.id, discussion.establishmentContact.contactMode, discussion.siret, discussion.appellationCode, discussion.potentialBeneficiary.firstName, discussion.potentialBeneficiary.lastName, discussion.potentialBeneficiary.email, discussion.potentialBeneficiary.phone, discussion.immersionObjective, discussion.potentialBeneficiary.resumeLink, discussion.createdAt.toISOString(), discussion.establishmentContact.email, discussion.establishmentContact.firstName, discussion.establishmentContact.lastName, discussion.establishmentContact.phone, discussion.establishmentContact.job, JSON.stringify(discussion.establishmentContact.copyEmails), discussion.address.streetNumberAndAddress, discussion.address.postcode, discussion.address.departmentCode, discussion.address.city, discussion.businessName, ]; + await this.executeQuery("insert", query, values); await this.insertAllExchanges(discussion.id, discussion.exchanges); } async update(discussion: DiscussionAggregate) { - await this.client.query( - `UPDATE discussions SET - contact_mode = $1, - siret = $2, - appellation_code = $3, - potential_beneficiary_first_name = $4, - potential_beneficiary_last_name = $5, - potential_beneficiary_email = $6, - potential_beneficiary_phone = $7, - immersion_objective = $8, - potential_beneficiary_resume_link = $9, - created_at = $10, - establishment_contact_email = $11, - establishment_contact_first_name = $12, - establishment_contact_last_name = $13, - establishment_contact_phone = $14, - establishment_contact_job = $15, - establishment_contact_copy_emails = $16, - street_number_and_address = $17, - postcode = $18, - department_code = $19, - city = $20, - business_name = $22 - WHERE id = $21`, - [ - discussion.establishmentContact.contactMode, - discussion.siret, - discussion.appellationCode, - discussion.potentialBeneficiary.firstName, - discussion.potentialBeneficiary.lastName, - discussion.potentialBeneficiary.email, - discussion.potentialBeneficiary.phone, - discussion.immersionObjective, - discussion.potentialBeneficiary.resumeLink, - discussion.createdAt.toISOString(), - discussion.establishmentContact.email, - discussion.establishmentContact.firstName, - discussion.establishmentContact.lastName, - discussion.establishmentContact.phone, - discussion.establishmentContact.job, - JSON.stringify(discussion.establishmentContact.copyEmails), - discussion.address.streetNumberAndAddress, - discussion.address.postcode, - discussion.address.departmentCode, - discussion.address.city, - discussion.id, - discussion.businessName, - ], - ); - + const query = ` + UPDATE discussions SET + contact_mode = $1, siret = $2, appellation_code = $3, potential_beneficiary_first_name = $4, potential_beneficiary_last_name = $5, + potential_beneficiary_email = $6, potential_beneficiary_phone = $7, immersion_objective = $8, potential_beneficiary_resume_link = $9, created_at = $10, + establishment_contact_email = $11, establishment_contact_first_name = $12, establishment_contact_last_name = $13, establishment_contact_phone = $14, establishment_contact_job = $15, + establishment_contact_copy_emails = $16, street_number_and_address = $17, postcode = $18, department_code = $19, city = $20, + business_name = $22 + WHERE id = $21`; + // prettier-ignore + const values = [ + discussion.establishmentContact.contactMode, discussion.siret, discussion.appellationCode, discussion.potentialBeneficiary.firstName, discussion.potentialBeneficiary.lastName, + discussion.potentialBeneficiary.email, discussion.potentialBeneficiary.phone, discussion.immersionObjective, discussion.potentialBeneficiary.resumeLink, discussion.createdAt.toISOString(), + discussion.establishmentContact.email, discussion.establishmentContact.firstName, discussion.establishmentContact.lastName, discussion.establishmentContact.phone, discussion.establishmentContact.job, + JSON.stringify(discussion.establishmentContact.copyEmails), discussion.address.streetNumberAndAddress, discussion.address.postcode, discussion.address.departmentCode, discussion.address.city, + discussion.id, + discussion.businessName, + ]; + await this.executeQuery("update", query, values); await this.clearAllExistingExchanges(discussion); await this.insertAllExchanges(discussion.id, discussion.exchanges); } @@ -125,8 +61,7 @@ export class PgDiscussionAggregateRepository async getById( discussionId: DiscussionId, ): Promise { - const pgResult = await this.client.query( - ` + const query = ` WITH exchanges_by_id AS ( SELECT discussion_id, ARRAY_AGG( @@ -175,33 +110,36 @@ export class PgDiscussionAggregateRepository FROM discussions LEFT JOIN exchanges_by_id ON exchanges_by_id.discussion_id = discussions.id WHERE id = $1 - `, - [discussionId], - ); - const discussion: DiscussionAggregate = pgResult.rows[0]?.discussion; - if (!discussion) return; - return { - ...discussion, - createdAt: new Date(discussion.createdAt), - immersionObjective: discussion.immersionObjective ?? null, - exchanges: discussion.exchanges.map((exchange) => ({ - ...exchange, - sentAt: new Date(exchange.sentAt), - })), - }; + `; + const values = [discussionId]; + const pgResult = await this.executeQuery("getById", query, values); + const discussion: DiscussionAggregate = pgResult.rows.at(0)?.discussion; + return discussion + ? { + ...discussion, + createdAt: new Date(discussion.createdAt), + immersionObjective: discussion.immersionObjective ?? null, + exchanges: discussion.exchanges.map((exchange) => ({ + ...exchange, + sentAt: new Date(exchange.sentAt), + })), + } + : undefined; } async countDiscussionsForSiretSince( siret: SiretDto, since: Date, ): Promise { - const pgResult = await this.client.query( - `SELECT COUNT(*) + const query = `SELECT COUNT(*) FROM discussions - WHERE siret = $1 AND created_at >= $2`, - [siret, since], + WHERE siret = $1 AND created_at >= $2`; + const values = [siret, since]; + const pgResult = await this.executeQuery( + "countDiscussionsForSiretSince", + query, + values, ); - return parseInt(pgResult.rows[0].count); } @@ -209,27 +147,35 @@ export class PgDiscussionAggregateRepository discussionId: DiscussionId, exchanges: ExchangeEntity[], ) { - const sql = format( - ` + const query = ` INSERT INTO exchanges (discussion_id, message, sender, recipient, sent_at, subject) VALUES %L - `, - exchanges.map((exchange) => [ - discussionId, - exchange.message, - exchange.sender, - exchange.recipient, - exchange.sentAt.toISOString(), - exchange.subject, - ]), + `; + // prettier-ignore + const values = exchanges.map( + ({ message, recipient, sender, sentAt, subject }) => + [ discussionId, message, sender, recipient, sentAt.toISOString(), subject], ); - - await this.client.query(sql); + await this.executeQuery("insertAllExchanges", format(query, values)); } private async clearAllExistingExchanges(discussion: DiscussionAggregate) { - await this.client.query("DELETE FROM exchanges WHERE discussion_id = $1", [ - discussion.id, - ]); + const query = "DELETE FROM exchanges WHERE discussion_id = $1"; + const values = [discussion.id]; + await this.executeQuery("clearAllExistingExchanges", query, values); + } + + private executeQuery( + queryName: string, + queryTextOrConfig: string | QueryConfig, + values?: I, + ): Promise> { + return this.client.query(queryTextOrConfig, values).catch((error) => { + logger.error( + { query: queryTextOrConfig, values, error }, + `PgDiscussionAggregateRepository_${queryName}_queryErrored`, + ); + throw error; + }); } }