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