iddocument.ts (3483B)
1 import { IDDocumentRepository } from "#core/application/id_document/id_document_repository.ts"; 2 import { 3 EntityLocked, 4 EntityNotFound, 5 } from "#core/application/repository_error.ts"; 6 import { IDDocument } from "#core/domain/id_document.ts"; 7 import { UUID } from "#core/domain/uuid.ts"; 8 import { 9 IDDocumentDto, 10 mapFromIDDocument, 11 mapToIDDocument, 12 } from "#infrastructure/memory/mapper/id_document.ts"; 13 import { mapError } from "#infrastructure/postgres/error.ts"; 14 import { Pool } from "$postgres"; 15 16 export class PostgresIDDocumentRepositoryAdapter 17 implements IDDocumentRepository { 18 constructor(readonly pool: Pool) { 19 } 20 21 async findOrCreate(uuid: UUID): Promise<IDDocument> { 22 try { 23 const connection = await this.pool.connect(); 24 try { 25 const result = await connection.queryObject< 26 IDDocumentDto 27 >`select * from "id_document" where "uuid" = ${uuid.toString()} limit 1;`; 28 if (result.rowCount !== 1) { 29 return new IDDocument(uuid); 30 } 31 return mapToIDDocument(result.rows[0]); 32 } finally { 33 connection.release(); 34 } 35 } catch (error) { 36 throw mapError(error); 37 } 38 } 39 40 async store(entity: IDDocument): Promise<void> { 41 try { 42 const dto = mapFromIDDocument(entity); 43 const connection = await this.pool.connect(); 44 const transaction = connection.createTransaction( 45 `txn_${dto.uuid}_${dto.version}`, 46 ); 47 try { 48 await transaction.begin(); 49 dto.version++; 50 if (dto.version === 1) { 51 await transaction.queryArray` 52 insert into "id_document" ( 53 "uuid", "state", "back", "front", "faceLeft", "faceFront", "faceRight", 54 "admin", "firstName", "lastName", "birthDate", "sex", "nationality", "country", 55 "version" 56 ) values ( 57 ${dto.uuid}, ${dto.state}, ${dto.back}, ${dto.front}, ${dto.faceLeft}, ${dto.faceFront}, ${dto.faceRight}, 58 ${dto.admin}, ${dto.firstName}, ${dto.lastName}, ${dto.birthDate}, ${dto.sex}, ${dto.nationality}, ${dto.country}, 59 ${dto.version} 60 ); 61 `; 62 await transaction.commit(); 63 entity.version = dto.version; 64 return; 65 } 66 const result = await transaction.queryObject<{ version: number }>` 67 update "id_document" set 68 "state" = ${dto.state}, 69 "back" = ${dto.back}, 70 "front" = ${dto.front}, 71 "faceLeft" = ${dto.faceLeft}, 72 "faceFront" = ${dto.faceFront}, 73 "faceRight" = ${dto.faceRight}, 74 "admin" = ${dto.admin}, 75 "firstName" = ${dto.firstName}, 76 "lastName" = ${dto.lastName}, 77 "birthDate" = ${dto.birthDate}, 78 "sex" = ${dto.sex}, 79 "nationality" = ${dto.nationality}, 80 "country" = ${dto.country}, 81 "version" = "version" + 1 82 where uuid = ${dto.uuid} 83 returning version; 84 `; 85 if (result.rowCount !== 1) { 86 transaction.rollback(); 87 throw new EntityNotFound(dto.uuid); 88 } 89 if (result.rows[0].version === dto.version) { 90 await transaction.commit(); 91 entity.version = dto.version; 92 return; 93 } 94 transaction.rollback(); 95 throw new EntityLocked(); 96 } finally { 97 connection.release(); 98 } 99 } catch (error) { 100 throw mapError(error); 101 } 102 } 103 }