refactor: prepare for MikroORM storage support
[e-mobility-charging-stations-simulator.git] / src / performance / storage / MikroOrmStorage.ts
1 // Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
2
3 import { MikroORM as MariaDbORM, type Options as MariaDbOptions } from '@mikro-orm/mariadb'
4 import { MikroORM as SqliteORM, type Options as SqliteOptions } from '@mikro-orm/sqlite'
5
6 import { Storage } from './Storage.js'
7 import { type PerformanceRecord, type Statistics, StorageType } from '../../types/index.js'
8 import { Constants } from '../../utils/index.js'
9
10 export class MikroOrmStorage extends Storage {
11 private readonly storageType: StorageType
12 private orm?: SqliteORM | MariaDbORM
13
14 constructor (storageUri: string, logPrefix: string, storageType: StorageType) {
15 super(storageUri, logPrefix)
16 this.storageType = storageType
17 this.dbName = this.getDBName()
18 }
19
20 public async storePerformanceStatistics (performanceStatistics: Statistics): Promise<void> {
21 try {
22 await this.orm?.em.persistAndFlush({
23 ...performanceStatistics,
24 statisticsData: Array.from(performanceStatistics.statisticsData, ([name, value]) => ({
25 name,
26 ...value
27 }))
28 } satisfies PerformanceRecord)
29 } catch (error) {
30 this.handleDBError(this.storageType, error as Error, Constants.PERFORMANCE_RECORDS_TABLE)
31 }
32 }
33
34 public async open (): Promise<void> {
35 try {
36 if (this.orm == null) {
37 switch (this.storageType) {
38 case StorageType.SQLITE:
39 this.orm = await SqliteORM.init(this.getOptions() as SqliteOptions)
40 break
41 case StorageType.MARIA_DB:
42 case StorageType.MYSQL:
43 this.orm = await MariaDbORM.init(this.getOptions() as MariaDbOptions)
44 break
45 }
46 }
47 } catch (error) {
48 this.handleDBError(this.storageType, error as Error)
49 }
50 }
51
52 public async close (): Promise<void> {
53 try {
54 if (this.orm != null) {
55 await this.orm.close()
56 delete this.orm
57 }
58 } catch (error) {
59 this.handleDBError(this.storageType, error as Error)
60 }
61 }
62
63 private getDBName (): string {
64 if (this.storageType === StorageType.SQLITE) {
65 return `${Constants.DEFAULT_PERFORMANCE_DIRECTORY}/${Constants.DEFAULT_PERFORMANCE_RECORDS_DB_NAME}.db`
66 }
67 return this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '')
68 }
69
70 private getOptions (): SqliteOptions | MariaDbOptions {
71 return {
72 dbName: this.dbName,
73 entities: ['./dist/types/orm/entities/*.js'],
74 entitiesTs: ['./src/types/orm/entities/*.ts'],
75 clientUrl: this.getClientUrl()
76 }
77 }
78
79 private getClientUrl (): string | undefined {
80 switch (this.storageType) {
81 case StorageType.SQLITE:
82 case StorageType.MARIA_DB:
83 case StorageType.MYSQL:
84 return this.storageUri.toString()
85 }
86 }
87 }