feat: add pieces

This commit is contained in:
Alessandre Laguierce 2024-11-27 14:20:33 +01:00
parent afe50c6091
commit 54e113d8db
2 changed files with 110 additions and 55 deletions

View File

@ -1,7 +1,7 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { new_client } from '../db/db_client'; import { new_client } from '../db/db_client';
import { Colour, Pattern, Shape, Piece, ComplexPiece } from '../types/piece'; import { Colour, Pattern, Shape, Piece, ComplexPiece } from '../types/piece';
import { Either, eitherLeft, eitherRight } from '../utils/utils'; import { Either, eitherLeft, eitherRight, eitherFormatError } from '../utils/utils';
const getDefaultColour = () => ({ id_colour: -1, name: 'unknown' }); const getDefaultColour = () => ({ id_colour: -1, name: 'unknown' });
const getDefaultPattern = () => ({ id_pattern: -1, name: 'unknown' }); const getDefaultPattern = () => ({ id_pattern: -1, name: 'unknown' });
@ -9,146 +9,187 @@ const getDefaultShape = () => ({ id_shape: -1, name: 'unknown' });
const getDefaultPiece = () => ({ id_piece: -1, colour: getDefaultColour(), pattern: getDefaultPattern(), shape: getDefaultShape() }); const getDefaultPiece = () => ({ id_piece: -1, colour: getDefaultColour(), pattern: getDefaultPattern(), shape: getDefaultShape() });
async function getEntity<T>(table: string, column: string, value: string | number, f: (o: Object) => T): Promise<Either<T, string>> { async function getEntity<T>(table: string, column: string, value: string | number, f: (o: Object) => T): Promise<Either<T, string>> {
const client = new_client(); const client = new_client();
await client.connect(); await client.connect();
const res = await client.query(`SELECT * FROM ${client.escapeIdentifier(table)} WHERE $1=$2;`, [column, value]); const res = await client.query(`SELECT * FROM ${client.escapeIdentifier(table)} WHERE $1=$2;`, [column, value]);
if (res.rows.length === 0) { if (res.rows.length === 0) {
await client.end();
return eitherRight<T, string>('Not found in database.');
}
const entity: T = f(res.rows[0]);
await client.end(); await client.end();
return eitherLeft<T, string>(entity); return eitherRight<T, string>('Not found in database.');
}
const entity: T = f(res.rows[0]);
await client.end();
return eitherLeft<T, string>(entity);
} }
async function getEntities<T>(table: string, f: (o: Object) => T): Promise<Array<T>> { async function getEntities<T>(table: string, f: (o: Object) => T): Promise<Array<T>> {
const client = new_client(); const client = new_client();
await client.connect(); await client.connect();
const res = await client.query(`SELECT * FROM ${client.escapeIdentifier(table)};`); const res = await client.query(`SELECT * FROM ${client.escapeIdentifier(table)};`);
const arr: Array<T> = new Array(); const arr: Array<T> = new Array();
for (let i = 0; i < res.rows.length; ++i) { for (let i = 0; i < res.rows.length; ++i) {
arr.push(f(res.rows[i])); arr.push(f(res.rows[i]));
} }
await client.end(); await client.end();
return arr; return arr;
}
async function registerEntity<T>(table: string, colName: string, name: string, f: (o: Object) => T): Promise<T> {
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 T entity = f(res.rows[0]);
await client.end();
} }
const toColour: (o: Object) => Colour = o => { const toColour: (o: Object) => Colour = o => {
return { id_colour: o['id_couleur'], name: o['nom_couleur'] }; return { id_colour: o['id_couleur'], name: o['nom_couleur'] };
}; };
async function getColour(idOrName: number | string): Promise<Either<Colour, string>> { async function getColour(idOrName: number | string): Promise<Either<Colour, string>> {
return await getEntity<Colour>('couleurs', typeof idOrName !== 'number' ? 'nom_couleur' : 'id_couleur', idOrName, toColour); return await getEntity<Colour>('couleurs', typeof idOrName !== 'number' ? 'nom_couleur' : 'id_couleur', idOrName, toColour);
} }
async function getColours(): Promise<Array<Colour>> { async function getColours(): Promise<Array<Colour>> {
return await getEntities<Colour>('couleurs', toColour); return await getEntities<Colour>('couleurs', toColour);
} }
async function createColour(name: string): Promise<Colour> { async function createColour(name: string): Promise<Colour> {
return getDefaultColour(); return await registerEntity<Colour>('couleurs', 'nom_couleur', name, toColour);
} }
const toPattern: (o: Object) => Pattern = o => { const toPattern: (o: Object) => Pattern = o => {
return { id_pattern: o['id_motif'], name: o['nom_motif'] }; return { id_pattern: o['id_motif'], name: o['nom_motif'] };
}; };
async function getPattern(idOrName: number | string): Promise<Either<Pattern, string>> { async function getPattern(idOrName: number | string): Promise<Either<Pattern, string>> {
return await getEntity<Pattern>('motifs', typeof idOrName !== 'number' ? 'nom_motif' : 'id_motif', idOrName, toPattern); return await getEntity<Pattern>('motifs', typeof idOrName !== 'number' ? 'nom_motif' : 'id_motif', idOrName, toPattern);
} }
async function getPatterns(): Promise<Array<Pattern>> { async function getPatterns(): Promise<Array<Pattern>> {
return await getEntities<Pattern>('motifs', toPattern); return await getEntities<Pattern>('motifs', toPattern);
} }
async function createPattern(name: string): Promise<Pattern> { async function createPattern(name: string): Promise<Pattern> {
return getDefaultPattern(); return await registerEntity<Pattern>('motifs', 'nom_motif', name, toPattern);
} }
const toShape: (o: Object) => Shape = o => { const toShape: (o: Object) => Shape = o => {
return { id_shape: o['id_forme'], name: o['nom_forme'] }; return { id_shape: o['id_forme'], name: o['nom_forme'] };
}; };
async function getShape(idOrName: number | string): Promise<Either<Shape, string>> { async function getShape(idOrName: number | string): Promise<Either<Shape, string>> {
return await getEntity<Shape>('formes', typeof idOrName !== 'number' ? 'nom_forme' : 'id_forme', idOrName, toShape); return await getEntity<Shape>('formes', typeof idOrName !== 'number' ? 'nom_forme' : 'id_forme', idOrName, toShape);
} }
async function getShapes(): Promise<Array<Shape>> { async function getShapes(): Promise<Array<Shape>> {
return await getEntities<Shape>('formes', toShape); return await getEntities<Shape>('formes', toShape);
} }
async function createShape(name: string): Promise<Shape> { async function createShape(name: string): Promise<Shape> {
return getDefaultShape(); return await registerEntity<Shape>('formes', 'nom_forme', name, toShape);
} }
async function getPiece(id: number): Promise<Piece> { async function getPiece(id: number): Promise<Piece> {
return getDefaultPiece(); return getDefaultPiece();
} }
async function getPieces(): Promise<Array<Piece>> { async function getPieces(): Promise<Array<Piece>> {
return new Array(getDefaultPiece()); return new Array(getDefaultPiece());
} }
async function createPiece(colour: number, pattern: number, shape: number): Promise<Piece> { async function createPiece(colour: Colour, pattern: Pattern, shape: Shape): Promise<Piece> {
return getDefaultPiece(); 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.end();
return result;
} }
async function retrieveEntity<T>(f: (id: number) => Promise<Either<T, string>>, req: Request, res: Response) { async function retrieveEntity<T>(f: (id: number) => Promise<Either<T, string>>, req: Request, res: Response) {
const entity: Either<T, string> = await f(parseInt(req.params.id)); const entity: Either<T, string> = await f(parseInt(req.params.id));
if (entity.hasRight) { if (entity.hasRight) {
res.status(500).send(entity.right); res.status(500).send(entity.right);
return; return;
} }
res.send(entity.left); res.send(entity.left);
}
async function createEntity<T>(f: (o: Object) => T, table: string, colName: string, req: Request, res: Response) {
if (!req | !req.body | !req.body.name) {
res.status(400).send(eitherRight<T, string>('No field `name` in body.'));
return;
}
const entity: Either<T, string> = await registerEntity(table, colName, req.body.name, f);
if (entity.hasRight) {
res.status(500).send(entity.right);
return;
}
res.send(entity.left);
} }
const retrieveColour = async (req: Request, res: Response) => { const retrieveColour = async (req: Request, res: Response) => {
retrieveEntity<Colour>(getColour, req, res); retrieveEntity<Colour>(getColour, req, res);
}; };
const retrieveColours = async (req: Request, res: Response) => { const retrieveColours = async (req: Request, res: Response) => {
const colours: Array<Colour> = await getColours(); const colours: Array<Colour> = await getColours();
res.send(colours); res.send(colours);
}; };
const registerColour = (req: Request, res: Response) => { const registerColour = (req: Request, res: Response) => {
createEntity<Colour>("couleurs", getColour, req, res);
}; };
const retrievePattern = (req: Request, res: Response) => { const retrievePattern = (req: Request, res: Response) => {
retrieveEntity<Pattern>(getPattern, req, res); retrieveEntity<Pattern>(getPattern, req, res);
}; };
const retrievePatterns = (req: Request, res: Response) => { const retrievePatterns = (req: Request, res: Response) => {
res.send(getPatterns()); res.send(getPatterns());
}; };
const registerPattern = (req: Request, res: Response) => { const registerPattern = (req: Request, res: Response) => {
createEntity<Pattern>("motifs", getPattern, req, res);
}; };
const retrieveShape = (req: Request, res: Response) => { const retrieveShape = (req: Request, res: Response) => {
retrieveEntity<Shape>(getShape, req, res); retrieveEntity<Shape>(getShape, req, res);
}; };
const retrieveShapes = (req: Request, res: Response) => { const retrieveShapes = (req: Request, res: Response) => {
res.send(getShapes()); res.send(getShapes());
}; };
const registerShape = (req: Request, res: Response) => { const registerShape = (req: Request, res: Response) => {
createEntity<Shape>("formes", getShape, req, res);
}; };
const retrievePiece = (req: Request, res: Response) => { const retrievePiece = (req: Request, res: Response) => {
retrieveEntity<Piece>(getPiece, req, res); retrieveEntity<Piece>(getPiece, req, res);
}; };
const retrievePieces = (req: Request, res: Response) => { const retrievePieces = (req: Request, res: Response) => {
res.send(getPieces()); res.send(getPieces());
}; };
const registerPiece = (req: Request, res: Response) => { const registerPiece = (req: Request, res: Response) => {
const colour: Either<Colour, string> = getColour(req.body.colour);
if (colour.hasRight) {
res.status(500).send(eitherFormatError(colour));
return;
}
const pattern: Either<Pattern, string> = getPattern(req.body.pattern);
if (pattern.hasRight) {
res.status(500).send(eitherFormatError(pattern));
return;
}
const shape: Either<Shape, string> = getShape(req.body.shape);
if (shape.hasRight) {
res.status(500).send(eitherFormatError(shape));
return;
}
res.send(createPiece(colour.left, pattern.left, shape.left));
}; };
export { retrieveColour, retrieveColours, registerColour, retrievePattern, retrievePatterns, registerPattern, retrieveShape, retrieveShapes, registerShape, retrievePieces, registerPiece }; export { retrieveColour, retrieveColours, registerColour, retrievePattern, retrievePatterns, registerPattern, retrieveShape, retrieveShapes, registerShape, retrievePieces, registerPiece };

View File

@ -4,6 +4,13 @@ type Either<T, U> = {
right: U right: U
}; };
type Error = {
id: number,
message: string
};
type Result<T> = Error | T;
function eitherLeft<T, U>(left: T): Either<T, U> { function eitherLeft<T, U>(left: T): Either<T, U> {
return { hasRight: false, left: left, right: undefined }; return { hasRight: false, left: left, right: undefined };
} }
@ -12,4 +19,11 @@ function eitherRight<T, U>(right: U): Either<T, U> {
return { hasRight: true, left: undefined, right: right }; return { hasRight: true, left: undefined, right: right };
} }
export { Either, eitherLeft, eitherRight }; function eitherFormatError<T, string>(either: Either<T, string>): Result<T> {
if (either.hasRight) {
return { id: -1, message: either.right };
}
return either.left;
}
export { Either, eitherLeft, eitherRight, eitherFormatError };