build(deps-dev): apply updates
[e-mobility-charging-stations-simulator.git] / src / performance / storage / JsonFileStorage.ts
CommitLineData
edd13439 1// Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
c27c3eee 2
d972af76
JB
3import { closeSync, existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from 'node:fs';
4import { dirname } from 'node:path';
8114d10e 5
c1565026 6import { Storage } from './Storage';
7b5dbe91 7import { BaseError } from '../../exception';
268a74bb 8import { FileType, type Statistics } from '../../types';
9bf0ef23
JB
9import {
10 AsyncLock,
11 AsyncLockType,
12 Constants,
13 JSONStringifyWithMapSupport,
14 handleFileException,
15 isNullOrUndefined,
16} from '../../utils';
72f041bd 17
100a5301 18export class JsonFileStorage extends Storage {
2a370053
JB
19 private fd: number | null = null;
20
1f5df42a
JB
21 constructor(storageUri: string, logPrefix: string) {
22 super(storageUri, logPrefix);
23 this.dbName = this.storageUri.pathname;
72f041bd
JB
24 }
25
26 public storePerformanceStatistics(performanceStatistics: Statistics): void {
2a370053 27 this.checkPerformanceRecordsFile();
dd485b56 28 AsyncLock.acquire(AsyncLockType.performance)
1227a6f1 29 .then(() => {
d972af76 30 const fileData = readFileSync(this.dbName, 'utf8');
1227a6f1
JB
31 const performanceRecords: Statistics[] = fileData
32 ? (JSON.parse(fileData) as Statistics[])
33 : [];
34 performanceRecords.push(performanceStatistics);
9bf0ef23 35 writeFileSync(this.dbName, JSONStringifyWithMapSupport(performanceRecords, 2), 'utf8');
1227a6f1
JB
36 })
37 .catch((error) => {
fa5995d6 38 handleFileException(
1227a6f1
JB
39 this.dbName,
40 FileType.PerformanceRecords,
41 error as NodeJS.ErrnoException,
5edd8ba0 42 this.logPrefix,
1227a6f1 43 );
c63c21bc 44 })
1227a6f1 45 .finally(() => {
dd485b56 46 AsyncLock.release(AsyncLockType.performance).catch(Constants.EMPTY_FUNCTION);
1227a6f1 47 });
72f041bd 48 }
b652b0c3 49
2a370053 50 public open(): void {
b652b0c3 51 try {
9bf0ef23 52 if (isNullOrUndefined(this?.fd)) {
d972af76
JB
53 if (!existsSync(dirname(this.dbName))) {
54 mkdirSync(dirname(this.dbName), { recursive: true });
f682b2dc 55 }
d972af76 56 this.fd = openSync(this.dbName, 'a+');
a6ceb16a 57 }
b652b0c3 58 } catch (error) {
fa5995d6 59 handleFileException(
e7aeea18 60 this.dbName,
7164966d
JB
61 FileType.PerformanceRecords,
62 error as NodeJS.ErrnoException,
5edd8ba0 63 this.logPrefix,
e7aeea18 64 );
2a370053
JB
65 }
66 }
67
68 public close(): void {
69 try {
a6ceb16a 70 if (this?.fd) {
d972af76 71 closeSync(this.fd);
2a370053
JB
72 this.fd = null;
73 }
74 } catch (error) {
fa5995d6 75 handleFileException(
e7aeea18 76 this.dbName,
7164966d
JB
77 FileType.PerformanceRecords,
78 error as NodeJS.ErrnoException,
5edd8ba0 79 this.logPrefix,
e7aeea18 80 );
2a370053
JB
81 }
82 }
83
84 private checkPerformanceRecordsFile(): void {
73d09045 85 if (!this?.fd) {
7b5dbe91 86 throw new BaseError(
5edd8ba0 87 `${this.logPrefix} Performance records '${this.dbName}' file descriptor not found`,
e7aeea18 88 );
b652b0c3
JB
89 }
90 }
72f041bd 91}