import {DatabaseConnection} from "../Database/DatabaseConnection"; import {Model} from "../Models/Model"; import {Nullable} from "../types/Nullable"; import {DatabaseDefinition} from "../Database/DatabaseDefinition"; import {Container} from "../Container/Container"; import {EventHandler} from "../Events/EventHandler"; import {ElementCreatedEvent} from "../Events/EventClasses/ElementCreatedEvent"; export class Repository { constructor( protected readonly database: DatabaseConnection, public readonly schema: DatabaseDefinition, ) { } public create(instance: Partial): number | bigint { const columnNames = this.schema.columns.filter((column) => { return !column.primaryKey }).map((column) => { return column.name; }); const createObject = this.convertToCreateObject(instance); const keys = Object.keys(createObject); const missingColumns = columnNames.filter((columnName) => { return !keys.includes(columnName); }) if (missingColumns.length > 0) { throw new Error("Can't create instance, due to missing column values: " + missingColumns); } const sql = `INSERT INTO ${this.schema.name}(${Object.keys(createObject).join(',')}) VALUES (${Object.keys(createObject).map(() => "?").join(',')})`; const result = this.database.execute(sql, ...Object.values(createObject)); const id = result.lastInsertRowid; Container.get(EventHandler.name).dispatch(new ElementCreatedEvent(this.schema.name, instance, id)); return id; } public update(instance: Partial & { id: number }): boolean { const columnNames = this.schema.columns.filter((column) => { return !column.primaryKey }).map((column) => { return column.name; }); const createObject = this.convertToCreateObject(instance); const keys = Object.keys(createObject); const missingColumns = columnNames.filter((columnName) => { return !keys.includes(columnName); }) if (missingColumns.length > 0) { throw new Error("Can't create instance, due to missing column values: " + missingColumns); } const sql = `UPDATE ${this.schema.name} SET ${Object.keys(createObject).map((key) => `${key} = ?`).join(',')} WHERE id = ?`; const result = this.database.execute(sql, ...Object.values(createObject), instance.id); return result.changes > 0; } public getById(id: number): Nullable { const sql = `SELECT * FROM ${this.schema.name} WHERE id = ? LIMIT 1`; return this.convertToModelType(this.database.fetch(sql, id)); } public delete(id: number) { const sql = `DELETE FROM ${this.schema.name} WHERE id = ?`; return this.database.execute(sql, id); } protected convertToModelType(intermediateModel: IntermediateModelType | undefined): ModelType { return intermediateModel as unknown as ModelType; } protected convertToCreateObject(instance: Partial): object { return instance; } }