From 2c01512c53ed145669d5aae8876d75b7e2e2a854 Mon Sep 17 00:00:00 2001 From: Alessandre Laguierce Date: Wed, 27 Nov 2024 15:55:06 +0100 Subject: [PATCH 1/2] feat: add pieces to box --- back-end/src/controllers/piece.controller.ts | 115 +----------------- back-end/src/services/box.service.ts | 24 +++- back-end/src/services/pieces.service.ts | 121 +++++++++++++++++++ back-end/src/types/box.ts | 4 + back-end/src/utils/utils.ts | 11 +- 5 files changed, 157 insertions(+), 118 deletions(-) create mode 100644 back-end/src/services/pieces.service.ts diff --git a/back-end/src/controllers/piece.controller.ts b/back-end/src/controllers/piece.controller.ts index 4223f7c..73a5d79 100644 --- a/back-end/src/controllers/piece.controller.ts +++ b/back-end/src/controllers/piece.controller.ts @@ -1,126 +1,13 @@ import { Request, Response } from 'express'; -import { new_client } from '../db/db_client'; import { Colour, Pattern, Shape, Piece, ComplexPiece } from '../types/piece'; import { Either, eitherLeft, eitherRight, eitherFormatError } from '../utils/utils'; +import { getEntity, getEntities, registerEntity, toColour, getColour, getColours, createColour, toPattern, getPattern, getPatterns, createPattern, toShape, getShape, getShapes, createShape, getPiece, getPieces, createPiece } from '../services/pieces.service'; const getDefaultColour = () => ({ id_colour: -1, name: 'unknown' }); const getDefaultPattern = () => ({ id_pattern: -1, name: 'unknown' }); const getDefaultShape = () => ({ id_shape: -1, name: 'unknown' }); const getDefaultPiece = () => ({ id_piece: -1, colour: getDefaultColour(), pattern: getDefaultPattern(), shape: getDefaultShape() }); -async function getEntity(table: string, column: string, value: string | number, f: (o: Object) => T): Promise> { - const client = new_client(); - await client.connect(); - const res = await client.query(`SELECT * FROM ${client.escapeIdentifier(table)} WHERE $1=$2;`, [column, value]); - if (res.rows.length === 0) { - await client.end(); - return eitherRight('Not found in database.'); - } - const entity: T = f(res.rows[0]); - await client.end(); - return eitherLeft(entity); -} - -async function getEntities(table: string, f: (o: Object) => T): Promise> { - const client = new_client(); - await client.connect(); - const res = await client.query(`SELECT * FROM ${client.escapeIdentifier(table)};`); - const arr: Array = new Array(); - for (let i = 0; i < res.rows.length; ++i) { - arr.push(f(res.rows[i])); - } - await client.end(); - return arr; -} - -async function registerEntity(table: string, colName: string, name: string, f: (o: Object) => T): Promise { - const client = new_client(); - await client.connect(); - const res = await client.query(`INSERT INTO ${client.escapeIdentifier(table)} (${client.escapeIdentifier(colName)}) VALUES ($1) RETURNING *;`, [name]); - const entity: T = f(res.rows[0]); - await client.end(); - return entity; -} - -const toColour: (o: Object) => Colour = o => { - return { id_colour: o['id_couleur'], name: o['nom_couleur'] }; -}; - -async function getColour(idOrName: number | string): Promise> { - return await getEntity('couleurs', typeof idOrName !== 'number' ? 'nom_couleur' : 'id_couleur', idOrName, toColour); -} - -async function getColours(): Promise> { - return await getEntities('couleurs', toColour); -} - -async function createColour(name: string): Promise { - return await registerEntity('couleurs', 'nom_couleur', name, toColour); -} - -const toPattern: (o: Object) => Pattern = o => { - return { id_pattern: o['id_motif'], name: o['nom_motif'] }; -}; - -async function getPattern(idOrName: number | string): Promise> { - return await getEntity('motifs', typeof idOrName !== 'number' ? 'nom_motif' : 'id_motif', idOrName, toPattern); -} - -async function getPatterns(): Promise> { - return await getEntities('motifs', toPattern); -} - -async function createPattern(name: string): Promise { - return await registerEntity('motifs', 'nom_motif', name, toPattern); -} - -const toShape: (o: Object) => Shape = o => { - return { id_shape: o['id_forme'], name: o['nom_forme'] }; -}; - -async function getShape(idOrName: number | string): Promise> { - return await getEntity('formes', typeof idOrName !== 'number' ? 'nom_forme' : 'id_forme', idOrName, toShape); -} - -async function getShapes(): Promise> { - return await getEntities('formes', toShape); -} - -async function createShape(name: string): Promise { - return await registerEntity('formes', 'nom_forme', name, toShape); -} - -async function getPiece(id: number): Promise> { - const client = new_client(); - await client.connect(); - const res = await client.query(`SELECT * FROM pieces NATURAL JOIN colorer NATURAL JOIN etre_forme NATURAL JOIN avoir_motif WHERE id_piece = $1`, [id]); - const result: Piece = { id_piece: res.rows[0]['id_piece'], colour: toColour(res.rows[0]), pattern: toPattern(res.rows[0]), shape: toShape(res.rows[0]) }; - return eitherLeft(result); -} - -async function getPieces(): Promise> { - const client = new_client(); - await client.connect(); - const res = await client.query(`SELECT * FROM pieces NATURAL JOIN colorer NATURAL JOIN etre_forme NATURAL JOIN avoir_motif;`); - const arr: Array = new Array(); - for (let i = 0; i < res.rows.length; ++i) { - arr.push({ id_piece: res.rows[i]['id_piece'], colour: toColour(res.rows[i]), pattern: toPattern(res.rows[i]), shape: toShape(res.rows[i]) }); - } - return arr; -} - -async function createPiece(colour: Colour, pattern: Pattern, shape: Shape): Promise { - const client = new_client(); - await client.connect(); - const res = await client.query(`INSERT INTO pieces () VALUES () RETURNING *;`); - const result: Piece = { id_piece: res.rows[0]['id_piece'], colour: colour, pattern: pattern, shape: shape }; - await client.query("INSERT INTO colorer (id_piece, id_couleur) VALUES ($1, $2);", [result.id_piece, colour.id_colour]); - await client.query("INSERT INTO etre_forme (id_forme, id_piece) VALUES ($1, $2);", [shape.id_shape, result.id_piece]); - await client.query("INSERT INTO avoir_motif (id_piece, id_motif) VALUES ($1, $2);", [result.id_piece, pattern.id_pattern]) - await client.end(); - return result; -} - async function retrieveEntity(f: (id: number) => Promise>, req: Request, res: Response) { const entity: Either = await f(parseInt(req.params.id)); if (entity.hasRight) { diff --git a/back-end/src/services/box.service.ts b/back-end/src/services/box.service.ts index 48db42b..0688c4d 100644 --- a/back-end/src/services/box.service.ts +++ b/back-end/src/services/box.service.ts @@ -1,6 +1,8 @@ import { new_client } from '../db/db_client'; import { Box } from '../types/box'; -import { Either, eitherLeft, eitherRight } from '../utils/utils'; +import { Piece } from '../types/piece'; +import { getPiece } from './pieces.service'; +import { Either, eitherLeft, eitherRight, Pair, createPair } from '../utils/utils'; type DBBox = { id_boite: number; @@ -8,11 +10,27 @@ type DBBox = { date_boite: string; }; -function db2box(data: DBBox): Box { +async function getPiecesFromBox(id_box: number): Promise>> { + const client = new_client(); + await client.connect(); + const res = await client.query(`SELECT * FROM contenir WHERE id_boite = $1;`, [ id_box ]); + const arr: Array> = new Array(); + for (let i = 0; i < res.rows.length; ++i) { + const piece: Either = await getPiece(res.rows[i]['id_piece']); + if (piece.hasRight) + continue; + arr.push(createPair(piece.left, res.rows[i]['quantite_contenir'] as number)); + } + await client.end(); + return arr; +} + +async function db2box(data: DBBox): Promise { const box: Box = { id: data.id_boite, title: data.titre_boite, date: new Date(data.date_boite), + pieces: await getPiecesFromBox(data.id_boite) }; return box; @@ -31,7 +49,7 @@ const getBox = async (idOrTitle: number | string): Promise> await client.end(); return eitherRight("Does not exist."); } - const box = db2box(res.rows[0]); + const box = await db2box(res.rows[0]); await client.end(); return eitherLeft(box); diff --git a/back-end/src/services/pieces.service.ts b/back-end/src/services/pieces.service.ts new file mode 100644 index 0000000..17adc7c --- /dev/null +++ b/back-end/src/services/pieces.service.ts @@ -0,0 +1,121 @@ +import { new_client } from '../db/db_client'; +import { Colour, Pattern, Shape, Piece, ComplexPiece } from '../types/piece'; +import { Either, eitherLeft, eitherRight, eitherFormatError } from '../utils/utils'; + +async function getEntity(table: string, column: string, value: string | number, f: (o: Object) => T): Promise> { + const client = new_client(); + await client.connect(); + const res = await client.query(`SELECT * FROM ${client.escapeIdentifier(table)} WHERE $1=$2;`, [column, value]); + if (res.rows.length === 0) { + await client.end(); + return eitherRight('Not found in database.'); + } + const entity: T = f(res.rows[0]); + await client.end(); + return eitherLeft(entity); +} + +async function getEntities(table: string, f: (o: Object) => T): Promise> { + const client = new_client(); + await client.connect(); + const res = await client.query(`SELECT * FROM ${client.escapeIdentifier(table)};`); + const arr: Array = new Array(); + for (let i = 0; i < res.rows.length; ++i) { + arr.push(f(res.rows[i])); + } + await client.end(); + return arr; +} + +async function registerEntity(table: string, colName: string, name: string, f: (o: Object) => T): Promise { + const client = new_client(); + await client.connect(); + const res = await client.query(`INSERT INTO ${client.escapeIdentifier(table)} (${client.escapeIdentifier(colName)}) VALUES ($1) RETURNING *;`, [name]); + const entity: T = f(res.rows[0]); + await client.end(); + return entity; +} + +const toColour: (o: Object) => Colour = o => { + return { id_colour: o['id_couleur'], name: o['nom_couleur'] }; +}; + +async function getColour(idOrName: number | string): Promise> { + return await getEntity('couleurs', typeof idOrName !== 'number' ? 'nom_couleur' : 'id_couleur', idOrName, toColour); +} + +async function getColours(): Promise> { + return await getEntities('couleurs', toColour); +} + +async function createColour(name: string): Promise { + return await registerEntity('couleurs', 'nom_couleur', name, toColour); +} + +const toPattern: (o: Object) => Pattern = o => { + return { id_pattern: o['id_motif'], name: o['nom_motif'] }; +}; + +async function getPattern(idOrName: number | string): Promise> { + return await getEntity('motifs', typeof idOrName !== 'number' ? 'nom_motif' : 'id_motif', idOrName, toPattern); +} + +async function getPatterns(): Promise> { + return await getEntities('motifs', toPattern); +} + +async function createPattern(name: string): Promise { + return await registerEntity('motifs', 'nom_motif', name, toPattern); +} + +const toShape: (o: Object) => Shape = o => { + return { id_shape: o['id_forme'], name: o['nom_forme'] }; +}; + +async function getShape(idOrName: number | string): Promise> { + return await getEntity('formes', typeof idOrName !== 'number' ? 'nom_forme' : 'id_forme', idOrName, toShape); +} + +async function getShapes(): Promise> { + return await getEntities('formes', toShape); +} + +async function createShape(name: string): Promise { + return await registerEntity('formes', 'nom_forme', name, toShape); +} + +async function getPiece(id: number): Promise> { + const client = new_client(); + await client.connect(); + const res = await client.query(`SELECT * FROM pieces NATURAL JOIN colorer NATURAL JOIN etre_forme NATURAL JOIN avoir_motif WHERE id_piece = $1`, [id]); + if (!res.rows[0]) { + return eitherRight("Nothing found"); + } + const result: Piece = { id_piece: res.rows[0]['id_piece'], colour: toColour(res.rows[0]), pattern: toPattern(res.rows[0]), shape: toShape(res.rows[0]) }; + return eitherLeft(result); +} + +async function getPieces(): Promise> { + const client = new_client(); + await client.connect(); + const res = await client.query(`SELECT * FROM pieces NATURAL JOIN colorer NATURAL JOIN etre_forme NATURAL JOIN avoir_motif;`); + const arr: Array = new Array(); + for (let i = 0; i < res.rows.length; ++i) { + arr.push({ id_piece: res.rows[i]['id_piece'], colour: toColour(res.rows[i]), pattern: toPattern(res.rows[i]), shape: toShape(res.rows[i]) }); + } + return arr; +} + +async function createPiece(colour: Colour, pattern: Pattern, shape: Shape): Promise { + const client = new_client(); + await client.connect(); + const res = await client.query(`INSERT INTO pieces () VALUES () RETURNING *;`); + const result: Piece = { id_piece: res.rows[0]['id_piece'], colour: colour, pattern: pattern, shape: shape }; + await client.query("INSERT INTO colorer (id_piece, id_couleur) VALUES ($1, $2);", [result.id_piece, colour.id_colour]); + await client.query("INSERT INTO etre_forme (id_forme, id_piece) VALUES ($1, $2);", [shape.id_shape, result.id_piece]); + await client.query("INSERT INTO avoir_motif (id_piece, id_motif) VALUES ($1, $2);", [result.id_piece, pattern.id_pattern]) + await client.end(); + return result; +} + +export { getEntity, getEntities, registerEntity, toColour, getColour, getColours, createColour, toPattern, getPattern, getPatterns, createPattern, toShape, getShape, getShapes, createShape, getPiece, getPieces, createPiece }; diff --git a/back-end/src/types/box.ts b/back-end/src/types/box.ts index 32012fb..75b5ca9 100644 --- a/back-end/src/types/box.ts +++ b/back-end/src/types/box.ts @@ -1,7 +1,11 @@ +import { Pair } from '../utils/utils'; +import { Piece } from './piece'; + type Box = { id: number; title: string; date: Date; + pieces: Array> }; export { Box }; diff --git a/back-end/src/utils/utils.ts b/back-end/src/utils/utils.ts index 067a770..5f05f77 100644 --- a/back-end/src/utils/utils.ts +++ b/back-end/src/utils/utils.ts @@ -4,6 +4,11 @@ type Either = { right: U }; +type Pair = { + first: T, + second: U +}; + type Error = { id: number, message: string @@ -26,4 +31,8 @@ function eitherFormatError(either: Either): Result { return either.left; } -export { Either, eitherLeft, eitherRight, eitherFormatError }; +function createPair(first: T, second: U): Pair { + return { first: first, second: second }; +} + +export { Either, eitherLeft, eitherRight, eitherFormatError, Pair, createPair }; From 24a12ea3b1c975b92eb4fa3b7dd100aaac21f182 Mon Sep 17 00:00:00 2001 From: Nemo D'ACREMONT Date: Wed, 27 Nov 2024 16:01:03 +0100 Subject: [PATCH 2/2] fix: use await to wait for map --- back-end/src/services/box.service.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/back-end/src/services/box.service.ts b/back-end/src/services/box.service.ts index 0688c4d..ce03d1b 100644 --- a/back-end/src/services/box.service.ts +++ b/back-end/src/services/box.service.ts @@ -58,9 +58,11 @@ const getBox = async (idOrTitle: number | string): Promise> const getAllBoxes = async () => { const client = new_client(); await client.connect(); + const res = await client.query("SELECT * FROM boites"); + await client.end(); - return res.rows.map(db2box); + return await Promise.all(res.rows.map(async (el) => { return await db2box(el) })); } const getAllBoxesFromDate = async (date: Date) => { @@ -73,8 +75,9 @@ const getAllBoxesFromDate = async (date: Date) => { const dateString = `${YYYY}-${MM}-${DD}`; const res = await client.query("SELECT * FROM boites WHERE date_boite > $1", [dateString]); + await client.end(); - return res.rows.map(db2box); + return await Promise.all(res.rows.map(async (el) => { return await db2box(el) })); } const boxService = {