diff options
Diffstat (limited to 'src/services/postDatabase.ts')
-rw-r--r-- | src/services/postDatabase.ts | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/services/postDatabase.ts b/src/services/postDatabase.ts new file mode 100644 index 0000000..e3be7bb --- /dev/null +++ b/src/services/postDatabase.ts | |||
@@ -0,0 +1,86 @@ | |||
1 | import fs from "fs/promises"; | ||
2 | import path from "path"; | ||
3 | import * as f from "fp-ts"; | ||
4 | import * as t from "io-ts"; | ||
5 | |||
6 | export const PostDatabaseEntryC = t.type({ | ||
7 | provider: t.literal("e926"), | ||
8 | id: t.number, | ||
9 | }); | ||
10 | |||
11 | export type PostDatabaseEntry = t.TypeOf<typeof PostDatabaseEntryC>; | ||
12 | |||
13 | export class PostDatabase { | ||
14 | private entries: PostDatabaseEntry[] = []; | ||
15 | |||
16 | private readonly filePath: string; | ||
17 | |||
18 | private isLoaded = false; | ||
19 | |||
20 | constructor(filename: string, private max?: number) { | ||
21 | this.filePath = path.join(process.cwd(), filename); | ||
22 | } | ||
23 | |||
24 | private async load() { | ||
25 | if (this.isLoaded) { | ||
26 | return; | ||
27 | } | ||
28 | |||
29 | try { | ||
30 | await fs.stat(this.filePath); | ||
31 | } catch { | ||
32 | await this.save(); | ||
33 | } | ||
34 | |||
35 | const fileContent = await fs.readFile(this.filePath, "utf8"); | ||
36 | const entries = t.array(PostDatabaseEntryC).decode(fileContent); | ||
37 | |||
38 | if (f.either.isRight(entries)) { | ||
39 | this.entries = this.max ? entries.right.slice(0, -1 * this.max) : entries.right; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | private async save() { | ||
44 | await fs.writeFile(this.filePath, JSON.stringify(this.entries), "utf8"); | ||
45 | } | ||
46 | |||
47 | async insertIfNotExists(entry: PostDatabaseEntry): Promise<boolean> { | ||
48 | await this.load(); | ||
49 | |||
50 | const has = !!this.entries.find((e) => e.provider === entry.provider && e.id === entry.id); | ||
51 | |||
52 | if (!has) { | ||
53 | this.entries.push(entry); | ||
54 | await this.save(); | ||
55 | } | ||
56 | |||
57 | return has; | ||
58 | } | ||
59 | |||
60 | async takeFirst(): Promise<PostDatabaseEntry | undefined> { | ||
61 | await this.load(); | ||
62 | const entry = this.entries.shift(); | ||
63 | await this.save(); | ||
64 | return entry; | ||
65 | } | ||
66 | |||
67 | async remove(entry: PostDatabaseEntry): Promise<boolean> { | ||
68 | await this.load(); | ||
69 | const i = this.entries.findIndex((e) => e.provider === entry.provider && e.id === entry.id); | ||
70 | |||
71 | if (i === -1) { | ||
72 | return false; | ||
73 | } | ||
74 | |||
75 | this.entries.splice(i, 1); | ||
76 | await this.save(); | ||
77 | return true; | ||
78 | } | ||
79 | |||
80 | async getCount() { | ||
81 | await this.load(); | ||
82 | return this.entries.length; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | export default PostDatabase; | ||