From 62a278a6e0334dd7ba7d1d914f369b30014900fb Mon Sep 17 00:00:00 2001 From: Gerald Schmittinger Date: Fri, 21 Feb 2025 00:24:10 +0100 Subject: [PATCH] feat(backend): Databank initialiseren Verbinding met databank aangemaakt, eerste entities toegevoegd, centrale API aangemaakt om omgevingsvariabelen voor onze app op te vragen. --- .gitignore | 6 ++- backend/src/entities/users/student.entity.ts | 6 +++ backend/src/entities/users/teacher.entity.ts | 7 ++++ .../src/entities/{ => users}/user.entity.ts | 6 +-- backend/src/mikro-orm.config.ts | 11 +++-- backend/src/orm.ts | 15 ++++++- backend/src/util/envvars.ts | 42 +++++++++++++++++++ docker-compose.yml | 3 +- 8 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 backend/src/entities/users/student.entity.ts create mode 100644 backend/src/entities/users/teacher.entity.ts rename backend/src/entities/{ => users}/user.entity.ts (67%) create mode 100644 backend/src/util/envvars.ts diff --git a/.gitignore b/.gitignore index 9bb07775..d28e7d73 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,9 @@ build/Release node_modules/ jspm_packages/ +# package-lock.json +backend/package-lock.json + # Snowpack dependency directory (https://snowpack.dev/) web_modules/ @@ -641,7 +644,8 @@ FodyWeavers.xsd .LSOverride # Icon must end with two \r -Icon +Icon + # Thumbnails ._* diff --git a/backend/src/entities/users/student.entity.ts b/backend/src/entities/users/student.entity.ts new file mode 100644 index 00000000..ab5a537a --- /dev/null +++ b/backend/src/entities/users/student.entity.ts @@ -0,0 +1,6 @@ +import {User} from "./user.entity"; +import { Entity } from '@mikro-orm/core'; + +@Entity() +export class Student extends User { +} diff --git a/backend/src/entities/users/teacher.entity.ts b/backend/src/entities/users/teacher.entity.ts new file mode 100644 index 00000000..0b3e8c18 --- /dev/null +++ b/backend/src/entities/users/teacher.entity.ts @@ -0,0 +1,7 @@ +import { Entity } from '@mikro-orm/core'; +import {User} from "./user.entity"; + +@Entity() +export class Teacher extends User { + +} diff --git a/backend/src/entities/user.entity.ts b/backend/src/entities/users/user.entity.ts similarity index 67% rename from backend/src/entities/user.entity.ts rename to backend/src/entities/users/user.entity.ts index f7b0c426..0da754f5 100644 --- a/backend/src/entities/user.entity.ts +++ b/backend/src/entities/users/user.entity.ts @@ -1,9 +1,9 @@ import { Entity, PrimaryKey, Property } from '@mikro-orm/core'; -@Entity() +@Entity({abstract: true}) export class User { - @PrimaryKey({ type: 'number' }) - id!: number; + @PrimaryKey({type: "string"}) + username!: string; @Property() firstName: string = ''; diff --git a/backend/src/mikro-orm.config.ts b/backend/src/mikro-orm.config.ts index c4302a37..d5e97046 100644 --- a/backend/src/mikro-orm.config.ts +++ b/backend/src/mikro-orm.config.ts @@ -1,9 +1,14 @@ -import { Options } from '@mikro-orm/core'; -import { PostgreSqlDriver } from '@mikro-orm/postgresql'; +import {Options} from '@mikro-orm/core'; +import {PostgreSqlDriver} from "@mikro-orm/postgresql"; +import {EnvVars, getEnvVar, getNumericEnvVar} from "./util/envvars"; const config: Options = { driver: PostgreSqlDriver, - dbName: 'dwengo', + host: getEnvVar(EnvVars.DbHost, {required: true}), + port: getNumericEnvVar(EnvVars.DbPort, {defaultValue: 5432}), + dbName: getEnvVar(EnvVars.DbName, {defaultValue: "dwengo"}), + user: getEnvVar(EnvVars.DbUsername, {required: true}), + password: getEnvVar(EnvVars.DbPassword, {required: true}), entities: ['dist/**/*.entity.js'], entitiesTs: ['src/**/*.entity.ts'], debug: true, diff --git a/backend/src/orm.ts b/backend/src/orm.ts index d9de328f..16727a76 100644 --- a/backend/src/orm.ts +++ b/backend/src/orm.ts @@ -1,6 +1,19 @@ import { MikroORM } from '@mikro-orm/core'; import config from './mikro-orm.config.js'; +import {EnvVars, getEnvVar} from "./util/envvars"; export default async function initORM() { - await MikroORM.init(config); + const orm = await MikroORM.init(config); + + // Update the database scheme if necessary and enabled. + if (getEnvVar(EnvVars.DbUpdate)) { + await orm.schema.updateSchema(); + } else { + const diff = await orm.schema.getUpdateSchemaSQL(); + if (diff) { + throw Error("The database structure needs to be updated in order to fit the new database structure " + + "of the app. In order to do so automatically, set the environment variable DWENGO_DB_UPDATE to true. " + + "The following queries will then be executed:\n" + diff) + } + } } diff --git a/backend/src/util/envvars.ts b/backend/src/util/envvars.ts new file mode 100644 index 00000000..f9bdfb50 --- /dev/null +++ b/backend/src/util/envvars.ts @@ -0,0 +1,42 @@ +const PREFIX = "DWENGO_"; +const DB_PREFIX = PREFIX + "DB_"; + +type EnvVar = {[key: string]: {name: string, required?: boolean, defaultValue?: boolean}}; + +export const EnvVars: EnvVar = { + DbHost: {key: DB_PREFIX + "HOST", required: true}, + DbPort: {key: DB_PREFIX + "PORT", defaultValue: 5432}, + DbName: {key: DB_PREFIX + "NAME", defaultValue: "dwengo"}, + DbUsername: {key: DB_PREFIX + "USERNAME", required: true}, + DbPassword: {key: DB_PREFIX + "PASSWORD", required: true}, + DbUpdate: {key: DB_PREFIX + "UPDATE", defaultValue: false}, +} as const; + +/** + * Returns the value of the given environment variable if it is set. + * Otherwise, + * - throw an error if the environment variable was required, + * - return the default value if there is one and it was not required, + * - return an empty string if the environment variable is not required and there is also no default. + * @param envVar The properties of the environment variable (from the EnvVar object). + */ +export function getEnvVar(envVar: EnvVar): string { + const value: string | undefined = process.env[envVar.key]; + if (value) { + return value; + } else if (envVar.required) { + throw new Error(`Missing environment variable: ${envVar.key}`); + } else { + return envVar.defaultValue || ""; + } +} + +export function getNumericEnvVar(envVar: EnvVar): number { + const valueString = getEnvVar(envVar); + const value = parseInt(valueString); + if (isNaN(value)) { + throw new Error(`Invalid value for environment variable ${envVar.key}: ${valueString}. Expected a number.`) + } else { + return value; + } +} diff --git a/docker-compose.yml b/docker-compose.yml index e8efb530..88b9f491 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,8 +6,7 @@ services: POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres ports: - - "5432:5432" - network_mode: "host" + - "5431:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./backend/config/db/init.sql:/docker-entrypoint-initdb.d/init.sql