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