import { z } from "zod"; import { JSONObject } from "../../JSON.ts"; import { Q, StoccaTreDbConn } from "../../database.ts"; import { Result, StoccaTreError } from "../../Result.ts"; export const IngredientSchema = z.object({ id: z.number(), name: z.string().nonempty(), displayName: z.string().nonempty(), displayNameDE: z.string().nonempty(), }); export const IngredientSchemaWithoutId = IngredientSchema.omit({ id: true }); export type IngredientModel = z.infer; export default class IngredientCollection { static readonly TABLE_NAME = "main.ingredients"; private db: StoccaTreDbConn; private mapById: Map = new Map(); constructor(database: StoccaTreDbConn) { this.db = database; } async addIngredient(ingredient: JSONObject): Promise> { const parsed = IngredientSchemaWithoutId.safeParse(ingredient); if (!ingredient.success) { return [new StoccaTreError("Ingredient definition was malformed.", 400)]; } const [error, result] = > await this.db.query( `INSERT INTO ${ IngredientCollection.TABLE_NAME } VALUES (DEFAULT, $name, $displayName, $displayNameDE) RETURNING *;`, parsed ); if (error) { return [error]; } if (result.length > 0) { return [, result[0]]; } return [new StoccaTreError("Ingredient wasn't inserted!")]; } async getById(id: number): Promise> { const found = this.mapById.get(id); if (found) { return [, found]; } const [error, result] = > await this.db.query(`SELECT * FROM ${ IngredientCollection.TABLE_NAME } WHERE id is $id`, { id }); if (error) { return [error]; } const ingredient = result[0]; this.mapById.set(ingredient.id, ingredient); return [, ingredient]; } async getAllIngredients(): Promise> { const [error, result] = > await this.db.query(`SELECT * FROM ${ IngredientCollection.TABLE_NAME }`); if (!error) { result.forEach((ingredient: IngredientModel) => this.mapById.set(ingredient.id, ingredient)); } else { return [error]; } return [, Array.from(this.mapById.values())]; } }